W3C home > Mailing lists > Public > public-webappsec@w3.org > February 2016

Re: Making it easier to deploy CSP.

From: Devdatta Akhawe <dev.akhawe@gmail.com>
Date: Fri, 12 Feb 2016 19:47:02 -0800
Message-ID: <CAPfop_0wiyrBvv8gUk-0TxKy16OoSLCeG2phDnGmq-2fKrLYrQ@mail.gmail.com>
To: Mike West <mkwst@google.com>
Cc: "public-webappsec@w3.org" <public-webappsec@w3.org>, Artur Janc <aaj@google.com>, Lukas Weichselbaum <lwe@google.com>, Michele Spagnuolo <mikispag@google.com>
Hey Mike

I am probably confused but would we get something similar by just using a
nonce- source and some UA detection to send the big whitelist for browsers
that don't support nonces? Is 'unsafe-dynamic' needed only for backwards
compatibility for browsers that don't support nonce source?


On 12 February 2016 at 05:56, Mike West <mkwst@google.com> wrote:

> Hello, lovely webappsecians!
> I've been talking to Google's security folks about their adventures in
> deploying CSP to Google products. The TL;DR is that they're scared of
> whitelists (because of all the legacy junk on `google.com` and `
> googleapis.com`), and are frustrated with loading widgets and libraries
> whose content they don't control. They love (cryptographic) nonces and
> hashes, and have a small proposal for a new source expression which would
> make deployment at Google (and hopefully elsewhere) easier.
> # Whitelists
> As it turns out, `google.com` and other origins we depend on are full of
> terrible endpoints that allow user-injected script (see `
> https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22`,
> for example). We mitigate this risk with extensive `script-src` directives
> full of deep paths, which is brittle, awkward, and sometimes impossible
> (because some folks dynamically generate all the things!). It's also
> vulnerable to open redirects stripping the path, and of course sprawling
> origins like ours have open redirects too. Huzzah for legacy!
> The security team here would be thrilled if they could use (cryptographic)
> nonces and hashes for everything instead of relying on whitelists.
> But:
> # Dynamic Content
> Widgets and libraries make this dream difficult, as they insist on loading
> code from various places, and don't do a good job explaining what code
> they'll actually need before doing so (I'm looking at you, Google Maps). We
> can certainly add all of these paths to the whitelists as well, but they
> change on a somewhat regular basis, and end up with the same drawbacks as
> noted above.
> As it turns out, in the presence of a (cryptographic) nonce, this is
> something that the library itself could deal with, by grabbing the token
> from somewhere on the page, and using it when injecting its own script. The
> token is implicitly a script-execution capability:
> ```
> var ce = document.createElement;
> window.nonce =
> document.querySelector('script[nonce]').getAttribute('nonce');
> document.createElement = function (e) {
>  var el = ce.apply(this, arguments);
>  el.setAttribute('nonce', window.nonce);
>  return el;
> };
> ```
> While we work on updating every library in the entire world to use this
> pattern, we're also experimenting with getting the browser to do the
> busywork for us, in a backwards compatible way:
> # 'unsafe-dynamic'
> We're proposing a new `'unsafe-dynamic'` source expression which has the
> following effects when added to the `script-src` directive:
> 1.  If neither a hash nor a nonce is present in the directive's source
> list, do nothing. Otherwise:
> 2.  Ignore all `scheme-source` and `host-source`source expressions, as
> well as `'unsafe-inline'`. This gives us backwards compatibility, and
> ensures that developers who opt-into this mechanism won't leave themselves
> open to whitelist-based vulnerabilities; if you use 'unsafe-dynamic',
> that's all you use. That is, given the policy: `script-src 'unsafe-inline'
> https://example.com/ 'nonce-abcdef' 'unsafe-dynamic'`, Safari would see
> `script-src 'unsafe-inline' https://example.com/` <https://example.com/>
> (as it doesn't support nonces, while supporting browsers would see
> `script-src 'nonce-abcdef' 'unsafe-dynamic'`.
> 3.  Skip CSP enforcement on script execution for `<script>` elements which
> are not "parser-inserted". This basically boils down to automatically
> applying the capability noted above for scripts inserted via something like
> `appendChild(createElement('script'))`. We're only focusing on
> non-parser-inserted scripts, as (anecdotally) `document.write` and
> `innerHTML` are significantly more likely to contribute to XSS than
> `appendChild`. Moreover, `appendChild` accounts for the large majority of
> intentionally inserted scripts, based on an analysis of several dozen
> popular origins.
> You can play with most of this in Chrome Canary (behind
> chrome://flags/#enable-experimental-web-platform-features). Based on some
> experimentation with a crazy nonce-injecting extension, a policy like
> `'unsafe-eval' 'nonce-abcdef' 'unsafe-dynamic'` allows strict whitelisting
> with very little breakage on various Google properties and a few other high
> profile sites. The folks I've CC'd have more details on those tests for
> y'all if you're interested.
> I'll write up a patch to CSP to spell this out in more detail, but I hope
> the overview here is enough to get some early feedback. :)
> -mike
Received on Saturday, 13 February 2016 03:47:50 UTC

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