script-src nonces vs hashes: when to use which
By Thomas Poyeton
Once you add a script-src directive to your Content-Security-Policy, inline
<script> blocks stop running unless you explicitly allow them. You have two
ways to do that: a nonce or a hash. They solve the same problem from
opposite directions.
Nonces: one random token per response
A nonce is a random, single-use value your server generates for each HTTP response and places both in the header and on the script tag:
Content-Security-Policy: script-src 'nonce-r4nd0m'
<script nonce="r4nd0m">/* allowed */</script>
The browser runs the inline script only if the tag's nonce matches the header.
Because the value is unguessable and changes every response, an attacker who
injects a <script> can't know the current nonce, so their script is blocked.
The catch: you must generate a fresh nonce on every response. Reusing a nonce across responses, or hard-coding one, defeats the whole mechanism.
Hashes: pin the exact bytes
A hash allowlists an inline script by the SHA hash of its contents:
Content-Security-Policy: script-src 'sha256-BpfBOAGstzX3x9…'
No per-request server logic is needed, which makes hashes ideal for static sites and inline scripts that never change. The trade-off is fragility: the hash covers the exact bytes between the tags, so a single added space invalidates it.
Which should you pick?
- Dynamic, server-rendered pages → nonce. You already render per-request, so emitting a fresh value is cheap.
- Static sites / unchanging inline scripts → hash. No server logic required.
- Many third-party scripts you don't control → consider
'strict-dynamic'alongside a nonce, so trusted scripts can load their own dependencies.
You can compute a hash with the free inline-script hash generator on this site.
Verifying the whole policy
Nonces and hashes only cover inline scripts. The rest of your script-src
(and every other directive) still needs to be correct. To grade a complete
Content-Security-Policy and catch known bypasses, run it through
CentralCSP's CSP evaluator.