Server Side Template Injection in Gorilla Mux
How Server Side Template Injection Manifests in Gorilla Mux
Server Side Template Injection (SSTI) in Go applications using Gorilla Mux arises not from the router itself, but from how handlers render templates with untrusted input. Gorilla Mux directs requests to handlers, and if those handlers use a template engine (like html/template, pongo2, or jet) with user-supplied data inserted directly into the template execution context, an attacker can inject template directives.
The vulnerability typically appears in code paths where:
- Query parameters, path variables, or request bodies are passed directly to
Execute,ExecuteTemplate, or similar methods without sanitization. - Dynamic template names are constructed from user input, allowing an attacker to reference arbitrary templates.
- Template context data (
.or...) includes unvalidated user input that is later accessed within the template using dot notation.
For example, a common Gorilla Mux pattern that is vulnerable:
func handler(w http.ResponseWriter, r *http.Request) {
// Vulnerable: userInput from query param is passed directly
userInput := r.URL.Query().Get("name")
tmpl, _ := template.ParseFiles("templates/greeting.html")
data := struct { Name string }{Name: userInput}
tmpl.Execute(w, data) // If greeting.html contains {{.Name}}, SSTI is possible
}An attacker could supply a payload like ?name={{printf "%T" .}} or, with engines supporting more directives, ?name={{.Global}} to probe for exposed Go variables or execute arbitrary methods. In pongo2, syntax like {{ ''.__class__ }} might be used. The key is that Gorilla Mux's role is routing; the SSTI flaw resides in the handler's template invocation logic.
Gorilla Mux-Specific Detection
Detecting SSTI in a Gorilla Mux application requires probing endpoints that likely render templates (e.g., .html responses) with payloads designed to trigger template evaluation. middleBrick's Input Validation check automates this by sending a sequence of syntactic payloads and analyzing responses for signs of template execution, such as:
- Mathematical evaluation (e.g.,
{{7*7}}returning49). - Access to internal objects (e.g.,
{{.Global}}revealing Go structs). - Error messages disclosing template engine specifics.
- Changes in response structure when using payloads like
{{-"test"-}}(trimming inhtml/template).
Because Gorilla Mux applications often use Go's standard html/template, middleBrick tailors payloads to its syntax while also testing for alternative engines. The scanner does not need to know the internal code; it performs a black-box assessment by observing output differences between benign and malicious inputs.
To scan your own Gorilla Mux API with middleBrick's CLI tool:
middlebrick scan https://api.example.com/v1/usersIn the resulting report, SSTI findings appear under the Input Validation category with a high severity rating. The report will include the exact payload used, the endpoint, and evidence (e.g., a response snippet showing 49 when {{7*7}} was injected), allowing you to pinpoint the vulnerable route in your Gorilla Mux router and the corresponding handler.
Gorilla Mux-Specific Remediation
Remediating SSTI in Gorilla Mux applications centers on secure template handling practices, leveraging Go's html/template auto-escaping by default. The core principle: never pass raw user input into a template's execution context as data that can be interpreted as a directive.
1. Use Type-Safe Data Structures
Pass structured data (like structs or maps) to templates, and access fields via dot notation in the template. Go's html/template will escape values automatically. Avoid maps with arbitrary keys if user input controls the key name.
// Safe: userInput is a string field, auto-escaped in template
data := UserData{Name: r.URL.Query().Get("name")}
tmpl.Execute(w, data)2. Avoid Dynamic Template Names from User Input
If template names must be dynamic, validate against a strict allowlist:
tmplName := mux.Vars(r)["template"]
allowed := map[string]bool{"profile": true, "settings": true}
if !allowed[tmplName] {
http.Error(w, "Invalid template", http.StatusBadRequest)
return
}
tmpl.ExecuteTemplate(w, tmplName+=".html", data)3. Use template.HTML Sparingly
Only use template.HTML for content you trust completely. Never assign user input to a template.HTML field.
4. Pre-Ascape or Validate Input
If you must accept limited HTML (e.g., from a rich-text editor), sanitize it with a library like bluemonday before passing to the template, and still store it as a string—not template.HTML—until the final render step where you explicitly convert it after sanitization.
middleBrick's remediation guidance in its reports will reference these patterns, mapping findings to OWASP API Top 10: API10:2023 – Unsafe Consumption of APIs (when templates consume external data) or API08:2023 – Security Misconfiguration (insecure template setup). By fixing the handler code associated with your Gorilla Mux routes, you close the SSTI vector without altering the router's configuration.
Frequently Asked Questions
Is Gorilla Mux itself vulnerable to SSTI?
How does middleBrick distinguish SSTI from other injection flaws?
{{7*7}}, {{.Global}}) and looks for evidence of template evaluation in responses, such as computed values or object dumps. This differs from SQLi or XSS payloads and is tuned for the output patterns of Go template engines.