CSP Nonces and Hashes
CSP nonces and hashes replace unsafe-inline by whitelisting exact script contents — a fresh nonce per response, or a hash of the inline script — keeping inline scripts while blocking injected ones.
Definition
A CSP nonce is a random value generated per response and attached both to the script-src directive and to each allowed script tag. A hash whitelists the exact bytes of a specific inline script. Both express allow this exact inline code instead of allow all inline code, defeating XSS that injects different content. Nonce validity is per-response and must be unpredictable.
Context and scope
Adopted when inline scripts cannot be removed. Nonces fit server-rendered pages; hashes fit static inline snippets. Strict CSP recipes combine nonce with strict-dynamic for loader scripts.
Common misconceptions
- A static nonce works once and forever — reusing a nonce across responses lets any injected script carry the same attribute
- Nonces and hashes whitelist files — they whitelist inline content; external scripts still need source allowlists or strict-dynamic
- Adding a nonce makes XSS impossible — CSP is a second line of defense after output encoding and sanitization
Anti-patterns
- Caching pages with embedded nonces and serving stale nonces that browsers will honor as valid
- Generating nonces with weak randomness or deriving them from predictable request properties
- Keeping unsafe-inline alongside nonces for old browsers and silently disabling the whole directive on modern ones
Related concepts
Related examples
Authoritative source
What it is
Inline scripts are how most XSS payloads execute. Source allowlists cannot express which inline script is legitimate. Nonces and hashes can: the page declares a per-response random value or a content digest, and only inline scripts carrying that exact marker run.
How it works
The server generates a cryptographically random nonce per request, emits it in the CSP header, and stamps every intended inline script with the matching attribute. Browsers refuse inline scripts without it. With strict-dynamic, a whitelisted loader may create further scripts, propagating trust. Hashes pin static snippets: change the script, change the hash.
When to use it
Server-rendered pages with a few inline bootstrap snippets want nonces. Fully static pages with stable inline scripts want hashes. Both pair with report-only rollout: ship CSP in report mode, burn down violations, then enforce.
Pitfalls
CDN or full-page caching that replays a nonce breaks enforcement or validity; cache must vary on the nonce or drop inline scripts. Nonce reuse across sessions or responses is a real vulnerability class. Frameworks differ in nonce plumbing for third-party widgets that inject inline scripts at runtime.