W3C home > Mailing lists > Public > public-webappsec@w3.org > April 2015

Re: HTML Imports and CSP

From: Brad Hill <hillbrad@gmail.com>
Date: Tue, 07 Apr 2015 23:43:33 +0000
Message-ID: <CAEeYn8iJaFUcEnbzYXyNcEdnPB7R2tCmr8vdsDykuLjkrhNEdg@mail.gmail.com>
To: Joel Weinberger <jww@chromium.org>, Nathan Sobo <nathan@github.com>, Jeffrey Yasskin <jyasskin@google.com>
Cc: Mike West <mkwst@google.com>, Dimitri Glazkov <dglazkov@google.com>, Devdatta Akhawe <dev.akhawe@gmail.com>, Justin Schuh <jschuh@google.com>, Justin Fagnani <justinfagnani@google.com>, "public-webappsec@w3.org" <public-webappsec@w3.org>
Except it's not the case that "anything goes" once you import a script.
 e.g. if I want to use ReCaptcha, though that's just:

<script src='https://www.google.com/recaptcha/api.js'></script>

But I need the following CSP whitelists for my page to actually satisfy its
dependencies:

script-src https://www.google.com/recaptcha/
https://www.gstatic.com/recaptcha/ https://apis.google.com/js/
https://apis.google.com/_/; frame-src https://www.google.com/recaptcha/;
style-src 'unsafe-inline'

There's the argument that script-src makes the page totally untrustworthy
anyway - but we are about to work on additions to CSP for use as a
confinement mechanism, too, which this would totally invalidate.

Encapsulation is great, but it has to go both ways.  If we allow a
component to hide its internals from the enclosing page AND also not
inherit the security policy of that page - but without being isolated from
it - we've not just reinvented the security issues of doing widgets as
<script> includes, we've actually made things worse.

I think it's reasonable to say that if a component is not self-contained,
it's not actually fully encapsulated, and needs to declare its external
dependencies for CSP compatibility, which is the same model we have for
script-src.

On Tue, Apr 7, 2015 at 4:20 PM Joel Weinberger <jww@chromium.org> wrote:

> On Tue, Apr 7, 2015 at 12:08 PM Brad Hill <hillbrad@gmail.com> wrote:
>
>> <hat=individual>
>>
>> Do I misunderstand the model for HTML imports here?  I thought there was
>> no new document context created and no security boundary between it and the
>> importing page.  (which makes me sad, and which I commented on early-on,
>> but am not aware that the model ever changed)
>>
> Yes, I think you're correct, but I think we're suggesting that this has to
> change. For better or for worse, CSP has assumed that "you" (the developer)
> have control of pretty much all of the document of your page, with the
> exception of scripts you import dynamically changing things.
>
> HTML Imports fundamentally change this because the entire premise is that
> document structure is brought in wholesale and hidden from the importing
> document. Requiring that developers understand that structure (a) violates
> the encapsulation that HTML imports are trying to provide, and (b) is
> probably next to impossible on a practical level.
>
>>
>> The idea that an import is not governed by the page into which it is
>> inlined seems very against the rest of the pattern of CSP.  It makes sense
>> for e.g. a Worker to come with its own policy, as they may be shared among
>> several resources, have a limited interface, and must be same origin.
>>
>> If I <script src=xyz> that content might further try to import other
>> content, but the CSP for the importing resource must allow it.  (ReCaptcha
>> is a good example of this pattern.)
>>
>> But if content that gets inlined directly into the DOM gets to supply its
>> own policy... well, how do we even distinguish at that point which requests
>> are coming from it vs. the importing context?  And why isn't that just a
>> total invalidation of the CSP policy?
>>
> Yes, this is the hard part, and I'm not sure we resolved it. I suspect
> that, inevitably, this has the potential to lead to confusing cases where
> an imported document modifies something that's "part of" the
> "outer"/"importing" document, and then it will be confusing which CSP
> applies. Having dealt with something similar in the case of Chrome
> extensions, I suspect the answer is "if you modify the importing document,
> the change is subject to the importing document's CSP, so tread carefully."
>
>>
>> As someone who might be applying a policy to try to contain code (no,
>> random n00b developer, you can't just can't add that .js from jquery's CDN,
>> and sorry 3rd-party ad, you can't XHR to evil.com) this means I either
>> have to totally disallow imports, or it's goat-rodeo time.
>>
> Yeah, agreed. That's true of scripts, too. Isn't that what "default-src"
> is for?
>
>>
>> :(
>>
>> If an import becomes part of the resource, it should be governed by
>> policy delivered with that resource.  If that means you have to understand
>> the dependencies of things you import, (and they have to document and
>> conform to them!) I'm not sure that is a bad thing, either.
>>
> I think that, as a practical matter, we're already seeing that knowledge
> of a module's structure isn't a reasonable thing to require or assume. We
> escape this with script-src because we say "anything goes once you include
> a script," but the earlier parts of this thread were making the case that
> we shouldn't do that with HTML imports.
>
> Lots of imports assume policies that importing documents don't assume
> (e.g. inline scripts or img sources). Your suggestion either means that for
> foobar.com to use some BigCompaniesAwesomeModule that has inline scripts,
> they need to either (a) allow inline scripts for foobar.com, or (b)
> convince BigCompany to change their module. (b) is unlikely and (a) should
> make us sad.
>
>>
>> -Brad
>>
>>
>> On Tue, Apr 7, 2015 at 10:56 AM Joel Weinberger <jww@chromium.org> wrote:
>>
>>> On Tue, Apr 7, 2015 at 10:22 AM Nathan Sobo <nathan@github.com> wrote:
>>>
>>>> > they'll also need to enable those, probably with hashes since
>>>> unsafe-inline enables too much.
>>>>
>>>> (Oops, forgot to reply all.)
>>>>
>>>> I hope you'll also consider a nonce-based solution for imports as it
>>>> will greatly simplify our implementation in Atom.
>>>>
>>> Nathan, can you explain how this solution isn't sufficient for Atom? Is
>>> it that you *want* the outer document to enforce a "minimum CSP" on
>>> imports, and this solution doesn't provide that?
>>>
>>> From a usability perspective, I think this does provide a solution for
>>> you because by default, imports wouldn't have a policy at all, so "anything
>>> goes." I abstractly agree that having a page require a "minimum" CSP for
>>> modules would make sense to some degree, but I think that's a separate
>>> conversation/feature request.
>>>
>>>>
>>>> On Tue, Apr 7, 2015 at 11:04 AM, Jeffrey Yasskin <jyasskin@google.com>
>>>> wrote:
>>>>
>>>>> On Tue, Apr 7, 2015 at 9:53 AM, Mike West <mkwst@google.com> wrote:
>>>>> > On Tue, Apr 7, 2015 at 5:43 PM, Dimitri Glazkov <dglazkov@google.com>
>>>>> wrote:
>>>>> >>>
>>>>> >>> On Tue, Apr 7, 2015 at 1:39 PM, Mike West <mkwst@google.com>
>>>>> wrote:
>>>>> >>>>
>>>>> >>>> After thinking about this a bit more over the holidays, I think
>>>>> I'm more
>>>>> >>>> in agreement with you than I thought, Dev. :)
>>>>> >>>>
>>>>> >>>> What do you think about this:
>>>>> >>>>
>>>>> >>>> 1. Move imports to `import-src` (we'll need to measure usage in
>>>>> Chrome,
>>>>> >>>> but assuming this is mostly an extension thing at this point, it
>>>>> should be
>>>>> >>>> doable).
>>>>> >>>>
>>>>> >>>> 2. Give imports their own policy (that is, no longer inherit from
>>>>> the
>>>>> >>>> containing document) like Workers and frames, which would enable
>>>>> them to
>>>>> >>>> either whitelist `unsafe-inline` themselves, or use nonces/hashes
>>>>> whatever.
>>>>> >>
>>>>> >>
>>>>> >> This seems encouraging. What is the bottom line for developers
>>>>> using CSP?
>>>>> >> What is the least that they need to do in order to make HTML
>>>>> Imports usable?
>>>>> >
>>>>> >
>>>>> > The very least? Nothing at all. No CSP, no problem, right?
>>>>> >
>>>>> > The least they should do to maintain the security invariants they
>>>>> had before
>>>>> > is add an `imports-src` directive to their policy that allows
>>>>> Imports from a
>>>>> > set of sources. We'd almost certainly want to change Chrome
>>>>> extension/app's
>>>>> > default CSP to include such a directive.
>>>>> >
>>>>> > Maybe `import-src` would even default to `script-src`, in the same
>>>>> way (the
>>>>> > deprecated) `frame-src` defaults to `child-src` (which defaults to
>>>>> > `default-src`)? We've avoided these chains in the past, but it might
>>>>> make
>>>>> > sense here, as Imports can and do execute script, and the vast
>>>>> majority of
>>>>> > sites wouldn't know that they should think about restricting them.
>>>>>
>>>>> Further, they should put a CSP on the HTML Imports themselves, right?
>>>>> Otherwise the Import can pull scripts from bad places and be XSS'ed
>>>>> itself. If the HTML Import contains inline script blocks, they'll also
>>>>> need to enable those, probably with hashes since unsafe-inline enables
>>>>> too much. Has anyone written a build step for grunt/gulp/etc that
>>>>> generates hashes for a static file? What needs to be done to serve
>>>>> those hashes from most CDNs?
>>>>>
>>>>> Jeffrey
>>>>>
>>>>
>>>>
Received on Tuesday, 7 April 2015 23:44:02 UTC

This archive was generated by hypermail 2.3.1 : Monday, 23 October 2017 14:54:12 UTC