Using template.JS with User Input
Passing user-controlled data to template.JS which bypasses JavaScript escaping.
XSS vulnerabilities occur when template.JS is used with dynamic or user-controlled content in Go templates. template.JS marks strings as safe JavaScript and disables automatic escaping, allowing attackers to inject malicious scripts that execute in users' browsers, steal sessions, manipulate DOM content, and perform unauthorized actions.
package main
import (
"fmt"
"html/template"
"net/http"
)
func dashboard(w http.ResponseWriter, r *http.Request) {
username := r.URL.Query().Get("username")
// VULNERABLE: template.JS disables escaping for JavaScript
jsCode := template.JS(fmt.Sprintf("var user = '%s';", username))
tmpl := `<html><head><script>
{{.JSCode}}
alert('Welcome ' + user);
</script></head></html>`
t := template.Must(template.New("dash").Parse(tmpl))
t.Execute(w, struct{ JSCode template.JS }{jsCode})
}
// Attack: username = "'; alert('XSS'); var dummy='"
// Result: var user = ''; alert('XSS'); var dummy='';
// This executes the attacker's JavaScriptpackage main
import (
"encoding/json"
"html/template"
"net/http"
)
func dashboard(w http.ResponseWriter, r *http.Request) {
username := r.URL.Query().Get("username")
// SECURE: marshal data as JSON
userData, _ := json.Marshal(map[string]string{
"username": username,
})
tmpl := `<html><head><script>
// Parse JSON data safely
var userData = JSON.parse({{.UserData}});
alert('Welcome ' + userData.username);
</script></head></html>`
t := template.Must(template.New("dash").Parse(tmpl))
data := struct{ UserData string }{string(userData)}
t.Execute(w, data)
}The vulnerable code uses template.JS with fmt.Sprintf(), bypassing JavaScript escaping and allowing attackers to inject malicious scripts. The secure version marshals data as JSON and lets the template engine automatically escape it, then parses it safely in JavaScript.
Passing user-controlled data to template.JS which bypasses JavaScript escaping.
Sourcery automatically identifies cross-site scripting via template.js in go and many other security issues in your codebase.