- From: Artur Janc <aaj@google.com>
- Date: Mon, 6 Jun 2016 19:10:22 +0200
- To: Mike West <mkwst@google.com>
- Cc: Devdatta Akhawe <dev.akhawe@gmail.com>, Brad Hill <hillbrad@gmail.com>, WebAppSec WG <public-webappsec@w3.org>, Christoph Kerschbaumer <ckerschbaumer@mozilla.com>, Daniel Bates <dabates@apple.com>, Devdatta Akhawe <dev@dropbox.com>
- Message-ID: <CAPYVjqp_GXJeNDhtW0zAH4RW4mP_DkRUa_-O4CivcJq2Oj4HGg@mail.gmail.com>
On Mon, Jun 6, 2016 at 5:48 PM, Mike West <mkwst@google.com> wrote: > On Mon, Jun 6, 2016 at 4:45 PM, Devdatta Akhawe <dev.akhawe@gmail.com> > wrote: >> >> Are there use-cases for these separately? I'm all for adding things to >>> the platform if they're useful, but I'm not convinced from this thread that >>> these keywords add anything other than complexity. That is, Brad can >>> accomplish the things he's interested in with two policies, which I think >>> actually turns out to be a more powerful primitive than splitting the >>> keywords. >>> >> >> hmm .. the use case I am interested in is script-src >> https://www.dropbox.com/script/require.js 'allow-dynamic' >> >> Right now, this would force me to use a nonce. The nonce then is a >> leakable token present in the HTML of the page. Not a huge risk, but still. >> > > I see. That makes sense to me: you want the loader functionality, but you > don't want the added surface area of the capability token. > > I think I agree that there are two orthogonal concerns here (loading an > initial script via a nonce, hash, or URL on the one hand, and allowing that > initial script to load other things on the other), and splitting them up > makes sense. I worry a bit that folks would simply slap the dynamic keyword > onto an already weak policy and call it done, but I suppose that doesn't > make things any worse than they are today. > This idea (splitting unsafe-dynamic into something like 'allow-dynamic' and 'drop-whitelist'; the names are for illustrative purposes only!) is very interesting to discuss, and I think it's a little more complicated than it seems. What we gain: 1. It's possible to apply CSP in places that can't or don't want to have nonces. For example for cache-able static HTML pages we couldn't easily use 'unsafe-dynamic' because we wouldn't have the capability to load external scripts via <script#src> -- hashes can whitelist inline scripts, but not external ones. If we made the split, pages could combine a whitelist and 'allow-dynamic' and be safe from DOM XSS if the whitelist isn't bypassable. 2. It's easier to understand the behavior of the policy -- we decouple the two aspects of unsafe-dynamic from each other. What we lose: 1. Policies with 'allow-dynamic' but without 'drop-whitelist' aren't backwards compatible and would require user-agent sniffing. That's because any dynamically loaded scripts would be blocked in older browsers (which don't support allow-dynamic), or they would have to be explicitly whitelisted, resulting in an insecure policy even in new browsers. Unless developers pay attention, it will be easier to create a policy that works in new browsers but breaks on older ones. 2. We depart from an approach that promises easier CSP adoption and also offers better security. If we decouple the adoption benefit (easier loading of dynamic scripts) from the security benefit (dropping the whitelist) then people will likely choose the adoption benefit without realizing that their policy offers no protection against XSS -- we already know that >95% of policies are in that boat and this is a *very* conservative estimate. I worry that we'd abandon a big chance to improve the CSP ecosystem. 3. Arguably, having more keywords substitutes one kind of complexity (understanding of the behavior of unsafe-dynamic) for another: there will be more switches in CSP and realistically 'allow-dynamic' and 'drop-whitelist' would almost always have to be used together in order to provide a security benefit. 4. (Maybe this doesn't matter as much) We introduce keywords which are still coupled and need to be implemented simultaneously, e.g. if a user-agent implements drop-whitelist but not allow-dynamic, pages will break. Based on my experience, drawbacks #1 and #2 are fairly substantial, and I'm worried that risking them to enable the nonce-less/static content case (#1) -- which seems to be the main benefit of the split -- could be the wrong trade-off. Could we enable the static content case by allowing hashes to whitelist external scripts, as Mike suggested below? This way we could build policies without nonces so the nonce-leaking concern would disappear (unless there's another case that I'm not thinking about?). Even absent that, I'd generally prefer to prioritize the "dynamic application" case where it's possible to use nonces, because this is where CSP has the highest potential benefit against XSS. > 'allow-dynamic' (or just 'dynamic', maybe?) and 'nonce-only'? > 'drop-whitelist' is a little too broad, since nonces are part of the > whitelist, and we're not dropping those. 'ignore-hosts'? > > Concretely, would Dropbox use one (or both?) of these keywords if we >>> implemented them? >>> >> >> Not really sure yet. But, I am inclined towards the script-src example >> above. >> > > Cool, good to hear, thanks! > > While we're on the topic, I'd like to harden that example via externalized > hashes (e.g. `sha256-abc...` would allow `<script integrity="sha256-abc..." > ...>` to load). I'd like to find a mechanism to do so in a backwards > compatible way. We discussed it briefly at our last meeting. Anyone have > any good ideas? :) > To properly discuss it, I'd suggest doing it on another thread, maybe? ;) FWIW my preference would be to allow hashes to whitelist script URLs rather than contents, and keep SRI as a mechanism to enforce integrity... Otherwise, the "static content" case will be difficult to achieve with hashes because any changes to the external scripts will break the policy, since the digest will no longer match.
Received on Monday, 6 June 2016 17:11:10 UTC