Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Cross-site scripting via HTML template escaping bypass

ID: go/html-template-escaping-bypass-xss
Kind: path-problem
Security severity: 6.1
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-079
   - external/cwe/cwe-116
Query suites:
   - go-code-scanning.qls
   - go-security-extended.qls
   - go-security-and-quality.qls

Click to see the query in the CodeQL repository

In Go, the html/template package has a few special types (HTML, HTMLAttr, JS, JSStr, CSS, Srcset, and URL) that allow values to be rendered as-is in the template, avoiding the escaping that all the other strings go through.

Using them on user-provided values allows for a cross-site scripting vulnerability.

Recommendation

Make sure to never use those types on untrusted content.

Example

In the first example you can see the special types and how they are used in a template:

package main

import (
	"html/template"
	"net/http"
)

func bad(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	username := r.Form.Get("username")
	tmpl, _ := template.New("test").Parse(`<b>Hi {{.}}</b>`)
	tmpl.Execute(w, template.HTML(username))
}

To avoid XSS, all user input should be a normal string type.

package main

import (
	"html/template"
	"net/http"
)

func good(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	username := r.Form.Get("username")
	tmpl, _ := template.New("test").Parse(`<b>Hi {{.}}</b>`)
	tmpl.Execute(w, username)
}
  • © GitHub, Inc.
  • Terms
  • Privacy