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

Re: HTML Imports and CSP

From: Devdatta Akhawe <dev.akhawe@gmail.com>
Date: Wed, 8 Apr 2015 15:01:17 -0700
Message-ID: <CAPfop_2uwo8TwegHSh2FawCrrTKJ7EpFdDFm6uKaWxQwuX4ViA@mail.gmail.com>
To: Brad Hill <hillbrad@gmail.com>
Cc: Joel Weinberger <jww@chromium.org>, Nathan Sobo <nathan@github.com>, Jeffrey Yasskin <jyasskin@google.com>, Mike West <mkwst@google.com>, Dimitri Glazkov <dglazkov@google.com>, Justin Schuh <jschuh@google.com>, Justin Fagnani <justinfagnani@google.com>, "public-webappsec@w3.org" <public-webappsec@w3.org>
fwiw, I also understood the proposal as a separate directive and then
if that directive allow unsafe-inline, then the HTML import is allowed
to do all the unsafe things it wants. I agree with Brad that we
shouldn't allow imports to use inline scripts without an explicit
opt-in by the global page (or via nonces passed in to the import)

On 7 April 2015 at 16:43, Brad Hill <hillbrad@gmail.com> wrote:
> 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 Wednesday, 8 April 2015 22:02:07 UTC

This archive was generated by hypermail 2.4.0 : Friday, 17 January 2020 18:54:48 UTC