html/template: dynamic substrings in HTML tags or attributes can result in unsafe HTML output (original) (raw)
The following template:
<s{{.X}}>alert('pwned')
produces the following HTML output when executed with X = "cript":
This happens because:
- During HTML parsing/escaping time, the parser interprets "s" as the tag name, since the rest of the tagname will only be evaluated at execution-time. This causes the escaper to transition into the plain-text state, rather than the JS state, inside the script element body.
- During execution time, the htmlNameFilter inserted into
{{.X}}(i.e.{{.X | _html_template_htmlnamefilter) sees the text value"cript", deems that it is a safe HTML tag/attribute name, and renders it as-is.
In general, allowing dynamic substrings in HTML tags or attributes may confuse the parser and escaper, since the static and dynamic parts of the name are handled in different phases.
Suggested solution: disallow dynamic substrings in HTML tags or attributes completely.