AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Content-Security-Policy Nonce Is Not Applied To Streamed Suspense Boundary Scripts In Pages Router SSR

When using Pages Router with streaming and Suspense boundaries, script tags generated for suspended components lack the CSP nonce attribute, causing them to be blocked under strict Content Security Policy, leading to hydration failures and broken interactivity.

highConfidence 78%Next.jsAffected V16.2.12

Origin Analysis

Next.js Pages Router streaming renders Suspense boundaries using React's renderToPipeableStream but does not pass the document's nonce value to React's nonce option, resulting in script tags inserted during streaming (via React's boundary completion) missing the nonce attribute that is present on initial shell scripts.
1. Create a Next.js Pages Router app with a Suspense boundary that streams content. 2. Configure a Content Security Policy with a nonce for scripts. 3. Start production server and visit the page. 4. View page source and observe that script tags within Suspense boundary outputs lack the nonce attribute while all other script tags have it.

Fixing Code Block

Edge Case Audit

This patch assumes ctx.renderOpts.nonce is always defined; in setups where a nonce is not configured, passing undefined may cause React to omit the attribute or log warnings. Test both with and without CSP nonce. The patch is specific to Pages Router; App Router uses a different renderer and may require a separate fix. Upgrading React or Next.js may change renderToPipeableStream behavior; re-verify after updates. If a regression occurs, revert this change and consider a user-land workaround such as injecting nonce via a custom Document or middleware. Concurrency: multiple requests with different nonces are safe because each render call receives its own context.

Ecosystem Topology