Render User Data with Contextual HTML Escaping
Render untrusted names, bodies, and links through html/template so contextual escaping blocks script injection and bad URLs.
Code
package main
import (
"bytes"
"fmt"
"html/template"
"strings"
)
type Comment struct {
Author string
Body string
Link string
}
func main() {
page := template.Must(template.New("comment").Parse(
`<article><h2>{{.Author}}</h2><p>{{.Body}}</p><a href="{{.Link}}">profile</a></article>`,
))
comment := Comment{
Author: "<b>Mallory</b>",
Body: `<script>alert("x")</script>`,
Link: "javascript:alert(1)",
}
var output bytes.Buffer
if err := page.Execute(&output, comment); err != nil {
panic(err)
}
rendered := output.String()
fmt.Println(rendered)
if strings.Contains(rendered, "<script>") {
panic("script tag was not escaped")
}
if !strings.Contains(rendered, "<script>") {
panic("expected escaped body text")
}
if !strings.Contains(rendered, "#ZgotmplZ") {
panic("expected dangerous URL to be blocked")
}
}
Report a problem with this exampleOpens a pre-filled issue on GitHub.