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, 22 Apr 2015 08:27:46 -0700
Message-ID: <CAPfop_2frN2V_pep=UkohF4jzEaGKhavH3vxi8a=ObSNOWRC7Q@mail.gmail.com>
To: Joel Weinberger <jww@chromium.org>
Cc: Brad Hill <hillbrad@gmail.com>, 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>
>    import-src: https://www.polymer-project.org
>    import-policy: 'nonce-1234'
>    (or maybe import-policy: 'unsafe-inline')
> And we could make the default import-policy strict-by-default if you have an
> import-src.

hmm... given how most of the other directives work, why not put the
unsafe-inline/nonce inside import-src?

cheers
dev

>>
>> 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.
>
> Can you elaborate? Which mechanisms and how would they totally invalidate
> this?
>>
>> >
>> > 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.
>
> It seems like there's a middle ground, which is once a module "touches" the
> outer page, it's subject to the page's policy. Additionally, we can say the
> module's CSP only applies at Document load or something, then the page's CSP
> applies. I'm just spit balling here.

Yes, but that

>
> I think that this doesn't differ all that much from what we do with
> extensions with Chrome when they inject scripts into a page. At that point,
> we say "when the script initially runs, we'll allow it to bypass the CSP of
> the page, but we won't do anything beyond that (e.g. in callbacks)".
>>
>> >
>> > 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.
>
> I think we're already seeing that this is a huge burden, perhaps impossible,
> especially with recursive modules or dynamically imported modules. Your
> script-src example is interesting to me, because that already is 'hard' to
> deal with, to my understanding, and I might even consider it a failure of
> CSP. And with HTML imports, we're talking about a much, much longer list of
> things to whitelist.
>
> So I would argue that this is saying, if the import developer doesn't
> present you with a whitelist of content to add to your CSP, you very well
> may not be able to use CSP at all for your document, and making developers
> choose between using CSP and using HTML imports is the worst of all worlds
> (and this is a battle we'll lose). Reporting is great, but it only goes so
> far, especially if modules change in the future.
>
> And, ultimately, this is sort of what the idea of a module giving it's own
> policy is, it just means that the outer document isn't managing it (other
> than perhaps some coarse grained controls as I suggested above).
>>
>> >
>> > 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, 22 April 2015 15:28:36 UTC

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