Inline ES Modules

Mike Samuel mikesamuel at gmail.com
Wed Jun 20 13:54:22 UTC 2018


On Tue, Jun 19, 2018 at 9:50 PM Darien Valentine <valentinium at gmail.com>
wrote:

> Aha! Thanks. I think I get what you mean now.
>
> Let’s say I have this CSP:
>
> ```
> content-security-policy: script-src 'nonce-foo'
> ```
>
> And I have this in my document:
>
> ```
> <script nonce=foo type=module>
>   import 'data:text/javascript,console.log(`bar`)';
> </script>
> ```
>
> Then the browser could theoretically ignore the absence of 'data:' in the
> CSP safely because the import statement here is part of a nonce-allowed
> script. And the unsafety is adding `data:` to the CSP (which would then be
> available for third party scripts I might also allow), not using `data:` in
> my own trusted modules; and there is a minor bit of unsafety associated
> with dynamic import, but it’s not in the same league as the unsafety
> potentially implied by a blanket permission for all `data:` URI sources.
>
> I was surprised that this nuance was considered. I figured it just blindly
> asked "is this source permitted by the CSP" without taking into account
> whether the trust from a parent resource could be implicitly extended. But
> I see you’re totally right:
>
> ```
> <!DOCTYPE html>
> <meta http-equiv=content-security-policy content="script-src 'nonce-foo'">
> <script nonce=foo type=module>
>   import 'data:text/javascript,document.open();document.writeln(`<p>static
> import of data URI module worked</p>`)';
>   document.writeln(`<p>nonce module worked</p>`);
>   import('data:text/javascript,document.writeln(`<p>dynamic import of data
> URI module worked</p>`)');
> </script>
> ```
>
> demo: https://necessary-hallway.glitch.me/
>
> All three seem to work! Very cool.
>

https://github.com/w3c/webappsec-csp/issues/243 : "Any protection against
dynamic module import?"
captures the discussion on this.


> Sorry for the diversion from the main topic. This was really interesting
> and I appreciate the explanation.
>
>
> On Tue, Jun 19, 2018 at 8:58 PM Mike Samuel <mikesamuel at gmail.com> wrote:
>
>> Sorry for the confusion.
>>
>> Nonces are just for elements with url attributes.
>>
>> I mentioned nonces to point out that strict CSP policies can allow some
>> data: urls without having to explicitly whitelist or hash the entire
>> content.
>>
>> Separately I wanted to say that there is no incompatibility between the
>> goals of CSP and import statements that use a data: module specifier, since
>> we already trust the compilation unit and there's no actual network message
>> leaked.
>>
>> But there is a risk with the import operator since it's input is not part
>> of an already trusted input.
>>
>> On Tue, Jun 19, 2018, 8:22 PM Darien Valentine <valentinium at gmail.com>
>> wrote:
>>
>>> Mike: Ah, cool, I didn’t realize that — I had thought that nonces were
>>> just for whitelisting inline script elements. How does one specify a nonce
>>> in association with a data URI? I’m having trouble turning up a description
>>> / example of how it would work. Or possibly I’m misunderstanding this quite
>>> a bit, hm ... I’m also confused by the relationship between import/import()
>>> and XSS that you’ve described.
>>>
>>> On Tue, Jun 19, 2018 at 8:06 PM Mike Samuel <mikesamuel at gmail.com>
>>> wrote:
>>>
>>>> CSP with data URIs is possible via nonce sources.  For data: module
>>>> descriptors browsers could safely skip the CSP check since it doesn't allow
>>>> XSS unless one can already specify an import statement which typically
>>>> means one can specify arbitrary JS.  That argument doesn't extend to the
>>>> import operator though so you'd have to tolerate assymetry there.
>>>>
>>>> On Tue, Jun 19, 2018, 7:57 PM Darien Valentine <valentinium at gmail.com>
>>>> wrote:
>>>>
>>>>> Andrea: That is a really interesting approach. I would point out that
>>>>> using data URIs for js means the `data:` scheme has to be a permitted
>>>>> source for script-src. This allowance has roughly the same security
>>>>> implications as permitting `unsafe-eval`. I know most people aren’t using
>>>>> CSPs yet, but personally I’d be wary of a solution that makes it harder to
>>>>> adopt a strong CSP.
>>>>>
>>>>> A super dorky/tangential aside that probably doesn’t matter at all but
>>>>> ... I notice you used application/javascript for the media type. There’s a
>>>>> contradiction between the IANA media type registry and the HTML 5 spec with
>>>>> regard to the "correct" media type to use for JS. RFC 4329 says
>>>>> application/javascript is the only value that should be used, while HTML
>>>>> says text/javascript is the only value that should be used. I believe (not
>>>>> sure though) that this is because it’s the most backwards-compatible value.
>>>>> Given that the media types registry seems to be basically dead to web
>>>>> standards (if we follow the registry we can’t serve or post a bunch of
>>>>> media types acknowledged or defined by web standards at all, including
>>>>> image/webp, application/csp-report, etc) and the code has to run in a
>>>>> browser, I’d tend to think HTML is the better spec to follow ... though I
>>>>> guess when two specs contradict each other it’s hard to make an objective
>>>>> case for one being more authoritative. (I’d be curious if there’s a
>>>>> specific reason you know of to prefer to RFC definition though. When
>>>>> standards don’t align it breaks my tiny heart.)
>>>>>
>>>>> On Tue, Jun 19, 2018 at 4:09 PM Andrea Giammarchi <
>>>>> andrea.giammarchi at gmail.com> wrote:
>>>>>
>>>>>> sorry, I meant:
>>>>>>
>>>>>> JSON.stringify('data:text/javascript,' +
>>>>>> moduleContentAfterTreeShaking);
>>>>>>
>>>>>>
>>>>>> On Tue, Jun 19, 2018 at 10:09 PM, Andrea Giammarchi <
>>>>>> andrea.giammarchi at gmail.com> wrote:
>>>>>>
>>>>>>>
>>>>>>> I think these are all nice to have features, but I also think we
>>>>>>>> have all the primitives we need to make it happen via pre-processing.
>>>>>>>>
>>>>>>>>>
>>>>>>> I meant even synchronously, with a pre-processor that replace the
>>>>>>> imported module with
>>>>>>>
>>>>>>> 'data:text/javascript,' +
>>>>>>> JSON.stringify(moduleContentAfterTreeShaking);
>>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>> es-discuss mailing list
>>>>> es-discuss at mozilla.org
>>>>> https://mail.mozilla.org/listinfo/es-discuss
>>>>>
>>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20180620/7d32d9b0/attachment-0001.html>


More information about the es-discuss mailing list