CSP uses nonce or hash-based script allowlisting
Why it matters
Domain-based CSP allowlists are bypassed by JSONP endpoints and CDN-hosted gadget scripts — any page served from an allowed domain becomes a script injection vector. Attackers exploit this to execute arbitrary JavaScript in your users' browsers, exfiltrating session tokens, credentials, or payment data. CWE-79 (XSS) and CWE-693 (Protection Mechanism Failure) both apply directly. OWASP A03 (Injection) explicitly calls out CSP bypass via allowlisted domains as an unmitigated XSS vector. Nonce or hash-based allowlisting closes this bypass completely because each nonce is request-unique and cannot be predicted or replicated from another origin.
Severity rationale
Critical because a bypassed CSP provides zero XSS protection — an attacker with a JSONP gadget on any allowlisted CDN achieves full script execution as if no policy existed.
Remediation
Switch from domain allowlists to per-request nonces in middleware.ts. Each nonce is cryptographically random and single-use, making CDN-gadget bypasses impossible.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64')
const csp = [
`default-src 'self'`,
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic'`,
`style-src 'self' 'nonce-${nonce}'`,
].join('; ')
const response = NextResponse.next()
response.headers.set('Content-Security-Policy', csp)
response.headers.set('x-nonce', nonce)
return response
}
Pass the nonce to every <Script nonce={nonce}> component. Remove all domain entries from script-src — they are no longer needed once 'strict-dynamic' is set.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Security Headers II Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-79
- cwe · CWE-693
- owasp:2021 · A03
- soc2:2017 · CC6.6 — Protection against threats from outside system boundaries
Taxons
History
- 2026-04-18·v1.0.0·Initial import from security-headers-ii·automated
- 2026-07-06·v1.0.1·Add SOC 2 TSC mapping (CC6.6) from the verified compliance crosswalk register (docs/compliance/).·by soc2-mapping-enrichment-ship-2