3

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).

Keith
  • 150,284
  • 78
  • 298
  • 434
  • They are not incompatible. You can create Web Components without online script if you want to make use of restrictive CSP. (Maybe Polymer is not the Best example of séparation of code, I gués it Will change in the future to meet those security requirements. – Supersharp Sep 05 '16 at 21:57
  • @Supersharp Web Components without embedded styles or scripts kind of defeats one of the main things that makes Web Components worthwhile (and makes ` – Keith Sep 06 '16 at 13:05
  • If you see Web Components as embedded inline scripts and styles then you're right they won't fit with hardened CSP. I use tens of web components, each using (at least) one ` – Supersharp Sep 06 '16 at 14:06
  • @Supersharp clearly that isn't all they are, but the encapsulation of components is one of their biggest advantages, it seems a very basic omission to not support that. – Keith Sep 07 '16 at 06:21
  • 2
    Polymer allows you to use external scripts and stylesheets in a dom-module template. It's not required that they're inline. – ebidel Sep 07 '16 at 15:17
  • @ebidel ah, that gives me a workaround so that I can use Polymer in secure environments. I was under the impression that encapsulation was one of the big strengths of using Web Component based libraries over frameworks - I think I must be misunderstanding the point. – Keith Sep 07 '16 at 16:05
  • 1
    To be clear, the styles will still be scoped to your shadow root and the JS you're defining is the element's `prototype`. Whether you use inline script/css or external script/css doesn't change that. – ebidel Sep 08 '16 at 01:08
  • @ebidel I see - that's still really useful, in terms of not cluttering global namespaces/styles. I was kind of hoping there was some kind of answer in CSP2 or some aspect of Shadow DOM I just hadn't understood. – Keith Sep 08 '16 at 11:01

0 Answers0