Skip to content

html/template: user-supplied escapers can undermine contextual auto-escaping #19336

Closed
@stjj89

Description

@stjj89

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

html/template rewrites pipelines and adds calls to the escaping functions necessary to correctly and safely embed the output of these pipelines in their HTML contexts. For example, the following pipeline:

<a href={{ . | formatAsLink }}>

is rewritten as

<a href={{ . | formatAsLink | _html_template_urlfilter | _html_template_urlnormalizer | _html_template_nospaceescaper }}>

by the html/template escaper, where formatAsLink is the name of a user-defined function, and the rest of the _html_* names are names of internally-defined escapers.

However, if the pipeline already contains any of the predefined escaper functions (i.e. html or urlquery), and some of the escapers-to-be-inserted are considered equivalent, the html/template escaper will attempt to merge the inserted escapers with the existing predefined escapers, in order. For example,

<a href={{ . | html | formatAsLink }}>

is rewritten as

<a href={{ . | _html_template_urlfilter | _html_template_urlnormalizer | html | formatAsLink }}>

since _html_template_nospaceescaper and html are considered equivalent, and the escaper preserves the order of the escaping operations (i.e. URL escaping first, then HTML escaping). However, in this example, the user-defined formatAsLink function determines the final output of the pipeline. If formatAsLink contains a bug that causes it to emit an unsafe URL, the rendered HTML will be vulnerable to Cross-Site Scripting (XSS).

In general, users can shoot themselves in the foot if they manually escape their pipelines with html or urlquery because of this escaper-merging behavior. This behavior should either be explicitly documented or changed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions