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

Re: HTML Imports and CSP

From: Joel Weinberger <jww@chromium.org>
Date: Sun, 12 Apr 2015 16:23:40 +0000
Message-ID: <CAHQV2KkKTiMNrhUTA5iHXd5CQfHoh56Gi5G7Qt+N3o0QbDyYHA@mail.gmail.com>
To: Devdatta Akhawe <dev.akhawe@gmail.com>, Brad Hill <hillbrad@gmail.com>
Cc: 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>
On Wed, Apr 8, 2015 at 3:01 PM Devdatta Akhawe <dev.akhawe@gmail.com> wrote:

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

That was  #6 in my original email, so I guess I was suggesting that as an
"additional" option. For example, we might have:
   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.

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

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 Sunday, 12 April 2015 16:24:09 UTC

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