package main
import (
"html/template"
"net/http"
"os"
"strconv"
)
func checkError(err error) {
if err != nil {
panic(err)
}
}
type HTMLAlias = template.HTML
// bad is an example of a bad implementation
func bad(req *http.Request) {
tmpl, _ := template.New("test").Parse(`Hi {{.}}\n`)
tmplTag, _ := template.New("test").Parse(`Hi \n`)
tmplScript, _ := template.New("test").Parse(``)
tmplSrcset, _ := template.New("test").Parse(``)
{
{
var a = template.HTML(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmpl.Execute(os.Stdout, a)) // $ Alert[go/html-template-escaping-bypass-xss]
}
{
{
var a template.HTML
a = template.HTML(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmpl.Execute(os.Stdout, a)) // $ Alert[go/html-template-escaping-bypass-xss]
}
{
var a HTMLAlias
a = HTMLAlias(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmpl.Execute(os.Stdout, a)) // $ Alert[go/html-template-escaping-bypass-xss]
}
}
}
{
var c = template.HTMLAttr(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmplTag.Execute(os.Stdout, c)) // $ Alert[go/html-template-escaping-bypass-xss]
}
{
var d = template.JS(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmplScript.Execute(os.Stdout, d)) // $ Alert[go/html-template-escaping-bypass-xss]
}
{
var e = template.JSStr(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmplScript.Execute(os.Stdout, e)) // $ Alert[go/html-template-escaping-bypass-xss]
}
{
var b = template.CSS(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmpl.Execute(os.Stdout, b)) // $ Alert[go/html-template-escaping-bypass-xss]
}
{
var f = template.Srcset(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmplSrcset.Execute(os.Stdout, f)) // $ Alert[go/html-template-escaping-bypass-xss]
}
{
var g = template.URL(req.UserAgent()) // $ Source[go/html-template-escaping-bypass-xss]
checkError(tmpl.Execute(os.Stdout, g)) // $ Alert[go/html-template-escaping-bypass-xss]
}
}
// good is an example of a good implementation
func good(req *http.Request) {
tmpl, _ := template.New("test").Parse(`Hello, {{.}}\n`)
{ // This will be escaped, so it shoud NOT be caught:
var escaped = req.UserAgent()
checkError(tmpl.Execute(os.Stdout, escaped))
}
{
// The converted source value does NOT flow to tmpl.Exec,
// so this should NOT be caught.
src := req.UserAgent()
converted := template.HTML(src)
_ = converted
checkError(tmpl.Execute(os.Stdout, src))
}
{
// The untrusted input is sanitized before use.
tmpl, _ := template.New("test").Parse(`