-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
I have a collection of templates t
for generating a small set of HTML pages. I made the mistake of reusing the template name across all page templates (and not use Clone()
to create independent sets of templates for each) and the result is no HTML escaping.
Essentially I would expect that if I use something like:
t, err := template.New("t").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
page, err := t.New("page").Parse(`{{template "T" .}}`)
...
err = page.Execute(out, "<script>alert('you have been pwned')</script>")
I will get properly escaped HTML:
Hello, <script>alert('you have been pwned')</script>!
Which is exactly what happens. But if I add a second t.New().Parse()
call after the first one:
t, err := template.New("t").Parse(`{{define "T"}}Hello, {{.}}!{{end}}`)
page1, err := t.New("page").Parse(`{{template "T" .}}`)
page2, err := t.New("page").Parse(`something else`)
...
err = page1.Execute(out, "<script>alert('you have been pwned')</script>")
I get unescaped text:
Hello, <script>alert('you have been pwned')</script>!
Working example at https://play.golang.org/p/iqskRxgJOa . Comment out line 13 and get properly escaped HTML output.
Depending on the contents of the second redefinition, sometimes HTML escaping automagically works (it works on the playground if you use the same content for page2
as for page1
, but for some reason not in my server. I'm pretty sure this has to do with the weird way associated templates share their namespace: the second template replaces the "page"
template in the namespace, but page1
is now in an inconsistent state in that it is different from the "page"
template from its own namespace. At this point an execution should either return with an error or automagically replace text
and Tree
with those in page2
(grabbing them from the namespace map). Or work properly, producing escaped HTML.
Using go version go1.9.1 linux/amd64
on Ubuntu 17.10.