Server Side Template Injection in Gorilla Mux (Go)
Server Side Template Injection in Gorilla Mux with Go
Server Side Template Injection (SSTI) in a Gorilla Mux service built with Go typically arises when user-controlled data is interpolated into a template that is parsed and executed on the server. Gorilla Mux is a popular HTTP router and dispatcher that does not render templates itself, but applications often pair it with Go’s html/template or text/template packages. If a developer retrieves a template name or dynamic content from request parameters and uses it to construct templates dynamically (for example, via template.New(userInput).Parse(userContent)), an attacker can inject template actions that read or access Go objects exposed to the template context.
In practice, this can occur when an endpoint accepts a template query parameter or a path variable to select a template file stored locally, and the application passes that input directly to the template engine without strict allowlisting. For example, a route like /render/{templateName} mapped via mux.NewRouter().HandleFunc("/render/{name}", handler) can become dangerous if the handler loads and executes {name} as a template without validating it. Attackers can then leverage SSTI to access the underlying http.Request, local filesystem paths, or environment variables, depending on what data has been injected into the template’s execution context.
An illustrative vulnerable handler might look like this, where the template name is taken directly from the URL variable without validation:
func renderHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
templateName := vars["name"]
// WARNING: directly using user input as template name/path
tmpl, err := template.ParseFiles("/templates/" + templateName + ".html")
if err != nil {
http.Error(w, "invalid template", http.StatusBadRequest)
return
}
data := map[string]string{"Message": "hello"}
tmpl.Execute(w, data)
}
An attacker could request /render/../../../etc/passwd or a specially crafted template that abuses Go template actions to enumerate or exfiltrate data. Because Gorilla Mux provides the variables map, developers must treat these values as untrusted and avoid using them to dynamically determine template paths or content. Even when using the standard ParseFiles or ParseGlob functions, input must be strictly validated against an allowlist of known-safe template identifiers to prevent template injection paths.
Go-Specific Remediation in Gorilla Mux
Remediation centers on strict allowlisting and avoiding dynamic template construction from user input. Instead of concatenating user-controlled strings into file paths or template names, map allowed template identifiers to predefined file paths or template contents. Validate incoming route variables explicitly before any filesystem interaction.
Below is a secure handler example that uses an allowlist map to ensure only known templates can be rendered:
var allowedTemplates = map[string]string{
"home": "home.html",
"about": "about.html",
"contact": "contact.html",
}
func safeRenderHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
templateKey := vars["name"]
filename, ok := allowedTemplates[templateKey]
if !ok {
http.Error(w, "template not found", http.StatusBadRequest)
return
}
tmpl, err := template.ParseFiles("/templates/" + filename)
if err != nil {
http.Error(w, "server error", http.StatusInternalServerError)
return
}
data := map[string]string{"Message": "secure"}
tmpl.Execute(w, data)
}
Additionally, when using template functions or data injection, ensure that the data passed to Execute is sanitized and does not include user-controlled structures that expose methods or fields unintentionally. Avoid passing raw http.Request or complex objects into templates unless necessary, and prefer explicit structs with only required exported fields. For applications that parse templates from external sources (such as plugin systems), consider using template.New("static").Funcs(customFuncs).Parse(source) with rigorous source validation and a deny-list of dangerous actions, while monitoring for anomalies consistent with SSRF or information disclosure.
Complement these code changes with automated scanning in your development lifecycle. Using the middleBrick CLI, you can run middlebrick scan <url> against your service to detect SSTI indicators in unauthenticated scans. For teams integrating security earlier, the GitHub Action can add API security checks to your CI/CD pipeline and fail builds if risk scores drop below your defined threshold, while the MCP Server enables scanning APIs directly from your IDE as you develop.