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

App Router Boundary (Loading/Template/Error) Chunk <Script> Is Emitted Without The CSP Nonce

When using a nonce-based strict CSP, Next.js App Router fails to add the nonce attribute to the parser-inserted <script> tag for Suspense boundary chunks (loading.tsx, template.tsx, error.tsx). This causes the script to be blocked by 'strict-dynamic' on full page loads, leading to console violations and potentially broken client-side functionality.

highConfidence 92%Next.jsAffected V16.2.11Affected V16.3.3Affected V16.4.0-Canary.10

Origin Analysis

In `packages/next/src/server/app-render/create-component-styles-and-scripts.ts` (compiled to `create-component-styles-and-scripts.js`), the script element for boundary chunks is created without passing `nonce: ctx.nonce`, while the analogous code in `get-layer-assets.ts` does include the nonce. As a result, boundary scripts are parser-inserted into the initial HTML without a nonce and are blocked by CSP strict-dynamic.
1. Clone https://github.com/Vatroslav/next-csp-nonce-repro. 2. Run `npm install && npm run build && npm start`. 3. Open http://localhost:3000/repro in a browser with the console open, using a full page load (hard reload or directly typing the URL). 4. Observe the CSP violation in the console, or run `curl -s http://localhost:3000/repro | grep -o '<script[^>]*>' | grep -v nonce` to see the missing nonce attribute.

Fixing Code Block

Edge Case Audit

This change may expose the nonce in the HTML only where it is already intended; no new risky exposure is introduced. However, if the application uses a nonce that changes between requests (recommended), any cached HTML or CDN-cached pages that include the old nonce will continue to be blocked until cache invalidation. To roll back, simply remove the `nonce: ctx.nonce` line from the script props. No other code depends on this prop.

Ecosystem Topology