- From: Devdatta Akhawe <dev.akhawe@gmail.com>
- Date: Fri, 12 Feb 2016 19:47:02 -0800
- 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>
- Message-ID: <CAPfop_0wiyrBvv8gUk-0TxKy16OoSLCeG2phDnGmq-2fKrLYrQ@mail.gmail.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? cheers Dev 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