W3C home > Mailing lists > Public > public-webapps@w3.org > April to June 2017

Secure composition of custom elements

From: Mike Samuel <mikesamuel@gmail.com>
Date: Thu, 29 Jun 2017 17:17:34 -0400
Message-ID: <CACod6GsUh7L78KwETx8DYo8AqBbRqDoiU0SfK96Q12oS2x-64g@mail.gmail.com>
To: public-webapps@w3.org
I've been looking into the security of webcomponents frameworks.
This might be of interest to framework developers and spec authors.

  <a href="{{ $uri }}">{{ $text }}</a>

In a traditional template system, if $text is a crafted input like
`<script>alert(1)</script>` then unintended code execution occurs.

Webcomponents frameworks don't suffer from this because the HTML
parser does not receive the payload, but when $uri is
`javascript:alert(1)`, the attacker controlled value reaches the URI
parser, and from there the JS interpreter.

Traditional frameworks can address this by autoescaping [1] --
building in knowledge of the 100+ elements and similar number of
attributes with special semantics to insert escaping directives.

  <a href="{{ $uri }}">{{ $text }}</a>
=> automagic happens =>
  <a href="{{ $uri |checkSafeUrl |escapeHtml }}">{{ $text |escapeHtml }}</a>

Well-trained code reviewers & security auditors might suggest the same
where auto-escaping is not an option.

That does not work for custom elements.  Consider that
<dom-module id="foo-element"><template>
  <a href="{{ $uri }}">{{ $text }}</a>
defines a <foo-element>.  It is simple enough that it can be similarly
checked by human reviewers or tweaked by compiler passes.

But add
<dom-module id="bar-element"><template>
  <foo-element url="{{ $url }}" text="Hello, World!"></foo-element>
and the picture is less clear.

An alert human reviewer might infer that a third-party value reaching $url
is a problem, but the vulnerability is indirect, so more mistakes may result.
An auto-escaping pass could insert escaping directives if it stands in a place
to do whole program analysis.
CSP, browser XSS heuristics, etc. are equally effective, but it would be nice
to have defense in depth.

The definition of <foo-element> is vulnerable because it uses an <a> element.
If instead, $url reached javascript that used a sandboxed iframe or
window.open, then it would not be vulnerable in the same way.

The vulnerability is due to an implementation detail that users of
<foo-element> should not need to worry about.  Application developers
and code reviewers should not bear the responsibility for keeping
attacker controlled values away from the link element that underlies

Introducing Polymer-resin [2]
Polymer resin hooks into polymer to vet the results of data binding
expressions just before they reach an IDL bound property.

Safe HTML types [3] allow a (runtime) type-safe way of avoiding false positives.

[1] https://developers.google.com/closure/templates/docs/security#autoescaping
[2] https://github.com/Polymer/polymer-resin
[3] https://github.com/google/safe-html-types/blob/master/doc/index.md
[4] slides: https://goo.gl/Nopoye

I'm most familiar with Polymer and would love to hear about what other
frameworks are doing to deal with this issue.

Received on Thursday, 29 June 2017 21:18:07 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:15:05 UTC