Skip to content

How to Configure CSP Nonce

Key idea:

CSP nonce — a random value, generated per request, included in the CSP header script-src 'nonce-XXX' and as the attribute <script nonce="XXX">. Lets a specific inline script execute without 'unsafe-inline', critical for XSS defence. Especially important for React SSR + legacy code.

Below: step-by-step, working examples, common pitfalls, FAQ.

Step-by-Step Setup

  1. Generate nonce per request: $nonce = base64_encode(random_bytes(16));
  2. Set CSP header: Content-Security-Policy: script-src 'self' 'nonce-<NONCE>' 'strict-dynamic'
  3. In HTML: <script nonce="<NONCE>">doStuff()</script>
  4. All other inline is blocked (as intended for XSS defence)
  5. For React/Next.js: via __webpack_nonce__ + middleware
  6. Verify: DevTools → Console → should be no "Refused to execute inline script"
  7. Enterno CSP Analyzer → grade = A

Working Examples

ScenarioConfig
PHP middleware$nonce = base64_encode(random_bytes(16)); header("Content-Security-Policy: script-src 'self' 'nonce-$nonce'");
Next.js middlewareconst nonce = Buffer.from(crypto.randomUUID()).toString('base64'); headers.set('Content-Security-Policy', `script-src 'self' 'nonce-${nonce}'`);
Inline script with nonce<script nonce="<?= $nonce ?>"> window.dataLayer = []; </script>
strict-dynamic (advanced)script-src 'nonce-XXX' 'strict-dynamic' # scripts loaded via nonce-script inherit trust
Report-Only for testingContent-Security-Policy-Report-Only: script-src 'self' 'nonce-XXX'; report-uri /csp-report

Common Pitfalls

  • Non-random nonce (timestamp, sequential) — attacker can predict
  • Reusing a nonce across requests — completely breaks security
  • Forgetting to add nonce to a legitimate inline script — blocked, sign-in form breaks
  • Google Analytics / GTM scripts don't expect nonce — use strict-dynamic or hash
  • CSP via HTML meta instead of HTTP header — ineffective for first-page XSS

Learn more

Frequently Asked Questions

Nonce vs hash — which?

Nonce — for dynamic HTML (per request). Hash — for static inline script (unchanged). In practice nonce + strict-dynamic covers 95% of cases.

What is strict-dynamic?

CSP3 directive: any script loaded via nonce/hash-script automatically inherits trust. Simplifies GTM/Analytics integration.

Does CSP work in IE?

IE 11 supports CSP 1 (basic). Nonce arrived in CSP 2 — no IE. Acceptable in 2026.

How do I check my CSP?

<a href="/en/csp">Enterno CSP Analyzer</a> → enter URL → grade + directive breakdown.