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

Re: Making it easier to deploy CSP.

From: Mike West <mkwst@google.com>
Date: Mon, 18 Apr 2016 18:42:36 +0200
Message-ID: <CAKXHy=cd04GdS9W2bXVLwcZc+V-RxqNHjNBDynzbTcix3DJb8w@mail.gmail.com>
To: "public-webappsec@w3.org" <public-webappsec@w3.org>
Cc: Lukas Weichselbaum <lwe@google.com>, Michele Spagnuolo <mikispag@google.com>, Artur Janc <aaj@google.com>, Devdatta Akhawe <dev.akhawe@gmail.com>, Martin Thomson <martin.thomson@gmail.com>, Tanvi Vyas <tanvi@mozilla.com>, Dan Veditz <dveditz@mozilla.com>, Christoph Kerschbaumer <ckerschbaumer@mozilla.com>, John Wilander <wilander@apple.com>, Rob Trace <Rob.Trace@microsoft.com>, Ted Dinklocker <Ted.Dinklocker@microsoft.com>, Crispin Cowan <crispin@microsoft.com>
Blink's intent to ship is at
https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/g3qEQkTv5dU.
I'd welcome your feedback, positive or not (though this forum is a better
one for technical disagreement :) ).

-mike

On Monday, 11 April 2016, Mike West <mkwst@google.com> wrote:

> Based on Artur, et al's experience deploying 'unsafe-dynamic' on Google
> properties, I think it's a good model to experiment with.
>
> From reading through this thread again, my takeaway is that Dev is
> skeptical about the backwards compatibility story, and believes we might be
> at the point where there are diminishing returns to extending the current
> model, as opposed to breaking it entirely with a versioning scheme of some
> sort. I'm not convinced we've hit that wall yet, but I agree with the
> underlying assertion that CSP is getting (even more) complicated.
>
> Whether or not CSP3 is the right time to introduce real syntax changes (
> https://tools.ietf.org/html/draft-reschke-http-jfv-03, anyone?), this
> seems like a pretty small complication to add for a pretty big benefit.
> I've taken a first pass at defining the behavior we're interested in (
> https://github.com/w3c/webappsec-csp/commit/6210614603184fa9d7e5ed02b34e08d9144c20fa),
> and it's something I'd like to ship somewhat quickly in Chrome.
>
> CCing some other browser vendor reps in the hopes that my interpretation
> is shared. :)
>
> -mike
>
> On Sun, Mar 27, 2016 at 9:17 AM, Artur Janc <aaj@google.com
> <javascript:_e(%7B%7D,'cvml','aaj@google.com');>> wrote:
>
>> As a quick update, we are currently testing 'unsafe-dynamic' on a few
>> user-facing sites, including https://bugs.chromium.org
>>
>> The relevant bits of the policy are:
>> Content-Security-Policy: script-src 'unsafe-inline' 'nonce-..'
>> https://www.gstatic.com/recaptcha/api2/ 'unsafe-dynamic'; object-src
>> 'none';
>>
>> On bugs.chromium.org the main application change was to add the `nonce'
>> attribute to trusted external scripts, e.g.
>> <script src="https://www.google.com/recaptcha/api.js"
>> nonce="..."></script>
>>
>> The ReCAPTCHA API loads additional external sub-scripts, and
>> 'unsafe-dynamic' allows them to execute. This has two main benefits for the
>> site:
>> 1. It facilitates creating a policy for users of most JS APIs -- the site
>> owner doesn't have to figure out the locations of all JS sub-resources
>> loaded by each API, as long the top-level script is trusted and given a CSP
>> nonce. It also reduces the potential for breakage if paths of sub-scripts
>> ever change.
>> 2. It makes for a stricter policy. With 'unsafe-dynamic', dangerous
>> resources in whitelisted domains [1,2] are no longer a problem because
>> trust is now based on the presence of a nonce and the whitelist is ignored.
>>
>> With a policy like the one above, browsers which support CSP, but don't
>> support nonces will allow scripts to execute based on 'unsafe-inline' and
>> the source whitelist. Browsers which support nonces but don't support
>> unsafe-dynamic will ignore 'unsafe-inline' and will rely on the nonce and
>> the whitelist. Browsers which support unsafe-dynamic will rely solely on
>> the nonce and will transitively trust dynamically created scripts, and will
>> additionally ignore the whitelist.
>>
>> Based on what we have seen so far this appears to be a fairly promising
>> approach and we will experiment with it in larger applications in the near
>> future.
>>
>> Cheers,
>> -Artur
>>
>> [1]
>> https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22
>> [2]
>> https://lcamtuf.blogspot.com/2011/08/subtle-deadly-problem-with-csp.html
>>
>> On Fri, Feb 12, 2016 at 2:56 PM, Mike West <mkwst@google.com
>> <javascript:_e(%7B%7D,'cvml','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
>>>
>>
>>
>

-- 
-mike
Received on Monday, 18 April 2016 16:43:06 UTC

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