- From: Adam Barth <w3c@adambarth.com>
- Date: Sat, 27 Apr 2013 08:57:12 -0700
- To: "public-webappsec@w3.org" <public-webappsec@w3.org>
- Cc: Mike West <mkwst@google.com>
As discussed on the mailing list and at the face-to-face, I've re-worked how nonces work in CSP 1.1. Instead of introducing a separate script-nonce directive, you can now specify a nonce as a source expression, similar to 'self' or 'unsafe-inline': https://dvcs.w3.org/hg/content-security-policy/rev/fef47b277f08 The specification of how this works is included in the following changes: https://dvcs.w3.org/hg/content-security-policy/rev/2ce7592cce47 https://dvcs.w3.org/hg/content-security-policy/rev/67e913d459af Here are the examples from <https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/csp-specification.dev.html#usage-4>: ----8<---- The script-src directive lets developers specify exactly which script elements on a page were intentionally included for execution. Ideally, developers would avoid inline script entirely and whitelist scripts by URL. However, in some cases, removing inline scripts can be difficult or impossible. For those cases, developers can whitelist scripts using a randomly generated nonce. Usage is straightforward. For each request, the server generates a unique value at random, and includes it in the Content-Security-Policy header: Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com 'nonce-$RANDOM' This same value is then applied as a nonce attribute to each script element that ought to be executed. For example, if the server generated the random value Nc3n83cnSAd3wc3Sasdfn939hc3, the server would send the following policy: Content-Security-Policy: default-src 'self'; script-src 'self' https://example.com 'nonce-Nc3n83cnSAd3wc3Sasdfn939hc3' Script elements can then execute either because their src URLs are whitelisted or because they have an appropriate nonce: <script> alert("Blocked because the policy doesn't have 'unsafe-inline'.") </script> <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa"> alert("Still blocked because nonce is wrong.") </script> <script nonce="Nc3n83cnSAd3wc3Sasdfn939hc3"> alert("Allowed because nonce is valid.") </script> <script src="https://example.com/allowed-because-of-src.js"></script> <script nonce="EDNnf03nceIOfn39fn3e9h3sdfa" src="https://elsewhere.com/blocked-because-nonce-is-wrong.js"></script> <script nonce="Nc3n83cnSAd3wc3Sasdfn939hc3" src="https://elsewhere.com/allowed-because-nonce-is-valid.js"></script> Note that the nonce's value is not a hash or signature that verifies the contents of the script resources. It's quite simply a random string that informs the user agent which scripts were intentionally included in the page. Script elements with the proper nonce execute, regardless of whether they're inline or external. Script elements without the proper nonce don't execute unless their URLs are whitelisted. Even if an attacker is able to inject markup into the protected resource, the attack will be blocked by the attacker's inability to guess the random value. ---->8---- I've wired nonces up to script-src and style-src. We can write them up to other directives if that would be useful. (I did script-src and style-src first because they're the two directives that block inline content, which is where nonce-based whitelisting has the greatest benefit.) This approach definitely isn't set in stone. Please let me know if you have any feedback on the approach or the details. Thanks! Adam
Received on Saturday, 27 April 2013 15:58:11 UTC