Skip to content

html/template: predefined HTML escaper does not properly escape user input #19345

@stjj89

Description

@stjj89

version: go version devel +4cce27a3fa Sat Jan 21 03:20:55 2017 +0000 linux/amd64
env: linux amd64

When we have

.X = `haha onclick=evil()`,

The following template

<a title={{.X}}>

evaluates to

<a title=haha&#32;onclick&#61;evil()>

which is properly escaped. However, the following template:

<a title={{.X | html}}>

evaluates to

<a title=haha onclick=evil()>

which is improperly escaped, and insecure.

This is happening because the html/template escaper considers the predefined global html function equivalent to its internal _html_template_nospaceescaper escaping directive. Since the former is already present in the pipeline, it does not insert the latter to prevent over-escaping (see original commit of this behavior here). However, the above example shows that these two escaping functions are not equivalent.

We should thoroughly re-evaluate the equivalency of predefined global escapers to internal escapers, or get rid of this logic entirely. If we go with the latter option, we could consider removing all user-supplied escapers before adding internal escaper directives, in order to prevent over-escaping.

See related issue 19336 for another security issue related to this equivalent-escapers logic.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions