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

script-src 'self' https://example.com 'nonce-nc34908WECd8f3'

From: Adam Barth <w3c@adambarth.com>
Date: Sat, 27 Apr 2013 08:57:12 -0700
Message-ID: <CAJE5ia8zisYkBtdc6FX4zxLdvE+p58pbz77w5SVO9tbMyJD3EQ@mail.gmail.com>
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

This archive was generated by hypermail 2.3.1 : Saturday, 27 April 2013 15:58:12 UTC