Part of the new Web Components spec is Shadow DOM - a way of embedding <style>
and <script>
resources with the component HTML itself.
As I understand the spec the Shadow DOM mimics how many existing controls already exist in most of the browsers - for instance a browser's native video player will have buttons and styles internally that are part of the control's DOM.
However, this appears to clash with Content Security Policy which disables eval
and inline scripting.
A simple example (which only works in browsers that support <template>
and createShadowRoot()
):
// Create the shadow DOM
var shadow = document.querySelector('#testOutput').createShadowRoot();
// Get the template fragment and add it to the shadow DOM
shadow.appendChild(document.querySelector('#testTemplate').content);
<template id="testTemplate">
<style>
.foo { color: #e00; }
</style>
<script>
alert('Hello from the component');
</script>
<div class="foo">bar</div>
</template>
<div id="testOutput">shadow</div>
Run this and you get red "bar" text and an alert.
Now apply CSP by adding a header that blocks inline scripts:
Content-Security-Policy:default-src 'self'; object-src 'none'; img-src 'self' data:;
Now the component just generates errors.
This would seem to make CSP and Web Components completely incompatible, which is odd because CSP is fairly mature (supported by everything current except IE11) and Web Components is very new. It would also completely rule out modular Web Component libraries from ever being viable for secure sites unless they can also be delivered as more monolithic JS/CSS.
Is there any way around this?
Is there a way to allow Shadow DOM in the CSP?
Is there a way to create Shadow DOM that sandboxes it in a way that CSP allows?
Is this due to some part of the Shadow DOM spec that hasn't been fully implemented yet?
Update 2017
It isn't really a problem with Shadow DOM, so much as <script>
tags embedded in it. That can be avoided, but is a problem for HTML imports, but that's really a different question (possibly moot now Chrome is giving up on them).