fix(cms): thread a per-request nonce through the admin CSP
The prod CSP emitted script-src 'strict-dynamic' with no nonce seed, blocking every Payload admin script (A8). Reuse the shared nonce-based withSecurityHeaders: Payload admin pages are always dynamically rendered, so Next propagates the nonce read from the forwarded request's CSP header onto the admin's scripts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
import { buildSecurityHeaders } from "@repo/core-shared/security";
|
||||
import type { NextRequest } from "next/server";
|
||||
import { NextResponse } from "next/server";
|
||||
import { withSecurityHeaders } from "@repo/core-shared/security/next";
|
||||
import type { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
export function middleware(_request: NextRequest): NextResponse {
|
||||
const mode = process.env.NODE_ENV === "production" ? "prod" : "dev";
|
||||
const secHeaders = buildSecurityHeaders({ mode });
|
||||
|
||||
const response = NextResponse.next();
|
||||
for (const [name, value] of Object.entries(secHeaders)) {
|
||||
response.headers.set(name, value);
|
||||
}
|
||||
return response;
|
||||
// Payload's admin UI is served by this Next.js app and is always dynamically
|
||||
// rendered, so the shared nonce-based middleware works here: it generates a
|
||||
// per-request nonce, threads it into the CSP, and sets the CSP on the
|
||||
// forwarded request headers — which is how Next propagates the nonce onto
|
||||
// the admin's scripts. Without a nonce, the prod CSP's `strict-dynamic`
|
||||
// script-src would block every Payload admin script.
|
||||
export function middleware(request: NextRequest): NextResponse {
|
||||
return withSecurityHeaders(request);
|
||||
}
|
||||
|
||||
export const config = {
|
||||
|
||||
Reference in New Issue
Block a user