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:
Matthias Hochmeister
2026-06-08 17:10:32 +02:00
parent 4707844dbc
commit d7c74aa041
3 changed files with 30 additions and 2 deletions

View File

@@ -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({

View File

@@ -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",