Fix BLOCKING review findings: /login route + CSP header (WS1)
Behebt zwei BLOCKING-Befunde aus dem Review zu "Projekt-Fundament & Design-System": 1. Route-Namens-Mismatch (Default-deny-Kerngarantie): Login-Seite lag unter (auth)/anmelden, der gesamte downstream Auth-/Gating-Vertrag im Plan erwartet aber /login (NextAuth pages.signIn, requireSession-Redirect, PUBLIC_ALLOWLIST, Middleware-Matcher, auth-gating.spec toHaveURL(/\/login/), Datei-Layout (auth)/login/...). Verzeichnis nach (auth)/login umbenannt; /login als kanonischen Pfad im Guard-Slot-Kommentar von (app)/layout.tsx dokumentiert, damit Workstream 3 dieselbe Route verwendet. 2. Fehlende Content-Security-Policy in SECURITY_HEADERS: Plan Z.1314 fordert CSP mit default-src 'self', img-src 'self' data: blob:, worker-src 'self' blob:, frame-ancestors 'none', form-action 'self'; die security-headers.spec prueft frame-ancestors 'none'. CSP ergaenzt, in Produktion strikt, im Dev-Modus gelockerte script-src/connect-src (unsafe-eval + ws:) fuer Next.js-HMR via NODE_ENV. Verifikation: tsc --noEmit, next lint, next build (Route /login, kein /anmelden) gruen; CSP zur Laufzeit fuer prod/dev geprueft. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,7 +8,10 @@ import { AppShell } from "@/components/layout/app-shell";
|
||||
//
|
||||
// import { requireSession } from "@/lib/auth/guards";
|
||||
// ...
|
||||
// await requireSession(); // leitet anonyme Aufrufe auf /anmelden um
|
||||
// await requireSession(); // leitet anonyme Aufrufe auf /login um
|
||||
//
|
||||
// Kanonischer Login-Pfad: /login (siehe (auth)/login/page.tsx). Dieselbe Route
|
||||
// nutzen NextAuth pages.signIn, PUBLIC_ALLOWLIST und die Gating-Specs.
|
||||
//
|
||||
// Lese-Seiten dürfen sich NICHT allein auf die Middleware verlassen.
|
||||
export default async function AppLayout({
|
||||
|
||||
@@ -1,8 +1,33 @@
|
||||
/**
|
||||
* Sicherheits-Header, eingehängt in next.config.ts.
|
||||
* CSP bewusst konservativ; bei Bedarf von Feature-Workstreams erweitert.
|
||||
*
|
||||
* Content-Security-Policy ist der zentrale Querschnitts-Schutz (Implementierungs-
|
||||
* plan Z.1314): in Produktion strikt mit default-src 'self', frame-ancestors 'none'
|
||||
* und form-action 'self'. Im Dev-Modus benötigt Next.js (HMR/React-Refresh) eine
|
||||
* gelockerte script-src/connect-src-Variante ('unsafe-eval' + ws: für den Dev-Socket).
|
||||
*/
|
||||
const isProd = process.env.NODE_ENV === "production";
|
||||
|
||||
const CSP = [
|
||||
"default-src 'self'",
|
||||
// Dev braucht eval (React Refresh) + inline; Prod bleibt strikt.
|
||||
isProd
|
||||
? "script-src 'self'"
|
||||
: "script-src 'self' 'unsafe-eval' 'unsafe-inline'",
|
||||
"style-src 'self' 'unsafe-inline'",
|
||||
"img-src 'self' data: blob:",
|
||||
"font-src 'self' data:",
|
||||
"worker-src 'self' blob:",
|
||||
// Dev: WebSocket für HMR erlauben.
|
||||
isProd ? "connect-src 'self'" : "connect-src 'self' ws: wss:",
|
||||
"frame-ancestors 'none'",
|
||||
"form-action 'self'",
|
||||
"base-uri 'self'",
|
||||
"object-src 'none'",
|
||||
].join("; ");
|
||||
|
||||
export const SECURITY_HEADERS: Record<string, string> = {
|
||||
"Content-Security-Policy": CSP,
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-Frame-Options": "DENY",
|
||||
"Referrer-Policy": "strict-origin-when-cross-origin",
|
||||
|
||||
Reference in New Issue
Block a user