Secure composition of custom elements

I've been looking into the security of webcomponents frameworks.
This might be of interest to framework developers and spec authors.


Problem
=======
```
  <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>
</template></dom-module>
```
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>
</template></dom-module>
```
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
<foo-element>.


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.

cheers,
mike

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