CSP Nonce
A CSP nonce authorizes selected inline scripts by placing a fresh, unpredictable token in both the Content-Security-Policy header and the corresponding script element. This lets an application retain tightly controlled inline JavaScript without broadly allowing `'unsafe-inline'`.
A Content Security Policy (CSP) tells the browser which sources of executable content are permitted. With a nonce-based policy, the server creates a cryptographically strong random value for a response and includes it in `script-src` as `'nonce-<value>'`.
The same nonce is added to each inline `<script>` element that the server intentionally wants to authorize. The browser executes a nonce-bearing script only when its nonce matches a nonce permitted by the CSP delivered with that response.
The nonce should be unpredictable and freshly generated for each HTTP response. A fixed, reused, or attacker-controlled nonce undermines the protection because an attacker who can learn or predict it may be able to construct an authorized script element.
In a Java backend, nonce generation commonly uses `SecureRandom`, followed by an encoding such as Base64. The server then injects the nonce into both the CSP response header and the rendered HTML. Frameworks or templating systems must take care to pass the exact same per-response value to both locations.
A nonce is not a substitute for output encoding or safe handling of untrusted data. CSP is a defense-in-depth control: applications should still prevent injection at its source, validate untrusted input where appropriate, and avoid constructing executable code from user-controlled data.
Key points
- Generate a fresh, unpredictable nonce for each response.
- Put the nonce in `script-src` using the `'nonce-...'` CSP syntax.
- Use the identical nonce on authorized inline `<script>` elements.
- Generate nonces with a cryptographically secure random source such as Java `SecureRandom`.
- Do not treat a nonce as a replacement for output encoding and other XSS defenses.
Interview questions
How does a CSP nonce allow an inline script to execute?
The server generates a random nonce for the response and places it in the CSP `script-src` directive. The same nonce is placed on the intended inline `<script>` element. The browser compares the script's nonce with the nonce authorized by the CSP. If they match, that script is permitted by the nonce-based policy.
Why must a CSP nonce be unpredictable and regenerated for each response?
The nonce acts as authorization for inline script execution, so an attacker who can predict or obtain a reusable nonce may be able to attach it to injected markup. Cryptographically secure randomness makes guessing the value impractical. Regenerating it per response also limits the usefulness of a nonce exposed in one response. Java applications can use `SecureRandom` for nonce generation.
How would you implement a nonce-based CSP in a Java web application?
At the beginning of request processing, I would generate a cryptographically random nonce and associate it with the current response or rendering context. I would construct the CSP header with `script-src 'nonce-<nonce>'`. The rendering layer would receive that same value and place it in the `nonce` attribute of approved inline scripts. Finally, I would ensure the nonce is never reused across independent responses and test that unauthorized inline scripts are blocked.
What is the difference between a CSP nonce and a CSP hash?
A nonce authorizes an inline script through a random token associated with the response. A CSP hash instead authorizes inline script content whose cryptographic hash matches a value declared in the policy. Nonces are convenient when the generated script content changes between responses. Hashes can be useful when the exact inline script content is stable.
Does using a CSP nonce by itself prevent XSS?
No. A nonce-based CSP is a defense-in-depth mechanism rather than a replacement for secure application design. If an application has an injection flaw, the CSP can reduce the set of executable scripts that an attacker can introduce, but other CSP weaknesses or application behaviors can still matter. The application should continue using contextual output encoding, safe DOM APIs, input handling, and appropriate framework protections.