feat(csp): nonce-based script-src replaces unsafe-inline + lazy service bearer #112
No reviewers
Labels
No labels
backend
bug
completed
documentation
duplicate
enhancement
feature
frontend
good first issue
help wanted
in-progress
invalid
performance
phase-1
Phase1
Phase2
Phase3
planning
question
refactor
security
test
testing
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Kalle/ATM!112
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/csp-nonce-hardening"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Plan
Das letzte offene
script-src 'unsafe-inline'schließen (Security-Audit-Follow-up): per-Request-Nonce statt globaler Inline-Freigabe. Nebenbei: PR-#85-Review-P2 beheben (Session-Mint bei jedem Cache-Hit).Outcome
src/lib/csp.ts— pure CSP-Builder:script-src 'self' 'nonce-<random>' 'unsafe-eval'(kein'unsafe-inline'mehr). Injizierte Inline-<script>-Tags ohne Nonce werden browser-seitig geblockt.src/middleware.ts— mint pro Response eine frische Nonce (crypto.randomUUID), setzt Request-CSP-Header (damit Next.js seine Hydration-Bootstrap-Scripts automatisch mit der Nonce stampft — live per curl bewiesen:nonce="…"-Attribute auf den_next-Script-Tags) + Response-CSP. Locale-Redirect (/ → /de, 307) trägt die Policy./api/*-CORS-Vertrag (Tauri Remote-Auth) unverändert.src/lib/tts-synth.ts+public-audio-route.ts—bearerjetztstring | (() => string); die Route übergibt eine Minting-Thunk → Service-Session entsteht nur noch bei echten Cache-Misses. Der heiße 17 ms-Cache-Hit-Pfad schreibt keine Session-Zeile + Store-Persist mehr (P2: Write-Amplification).next.config.js— Kommentar klargestellt: die dortige CSP ist nur noch Fallback für middleware-ferne Pfade.Impact on release goals
[ ]→[~].Blackbox
python3 scripts/blackbox_test.py --target testing→ nach Merge (Test-25-Statuszeile wird dort grün, prod-build rendert /de/auth/login 200)--base http://localhost:3000, dev-server ohne Backend): 70/86 grün; alle 7 neuen CSP-Checks grün (Nonce-Uniqueness über 2 Requests, kein unsafe-inline, Redirect-CSP, Baseline-Direktiven intakt). Die 16 Roten sind die dokumentierte Umgebungs-Baseline (15 identisch mit origin/dev-Vergleich + Test-25-Statuszeile env-bedingt: dev-mode-SSR-500).nonce=-Attribute auf Next-Bootstrap-Scripts (App blockt sich nicht selbst); 307 mit Policy.Six-perspectives check
Risk
'unsafe-eval'verbleibt bewusst (eigener dokumentierter Follow-up — kein stiller Rollback).Checklist
0bd51a8)This PR was created by an AI agent (OpenHands) on behalf of the user.
Verdict: Approve — P0–P3 keine Findings (self-review, iteration-loop Phase 8)
Scope des Reviews:
src/middleware.ts,src/lib/csp.ts,src/lib/tts-synth.ts,src/lib/public-audio-route.ts,next.config.js,scripts/blackbox_test.py(Test 25), 3 Test-Dateien.Geprüft:
script-srcverliert'unsafe-inline'und gewinnt'nonce-<random>'. Kein stilles Direktiven-Drop.content-security-policy+x-nonce) — der dokumentierte Weg; live per curl bewiesen:nonce="…"-Attribute auf den_next-Bootstrap-Script-Tags, zwei Requests → zwei Noncen. Die App blockt sich nicht selbst./api/*(OPTIONS 204, ACAO*) unverändert — per Unit-Test verriegelt (Tauri Remote-Auth regressionsfrei).'unsafe-eval'verbleibt bewusst und ist als eigener Follow-up dokumentiert (kein stiller Rollback des Audit-Befehls).Blackbox: lokal 70/86 (16 Rot = dokumentierte Umgebungs-Baseline: kein FastAPI, leerer Store, dev-mode-SSR-500 — identisch mit origin/dev-Vergleichslauf); alle 7 neuen CSP-Checks grün. Autoritativ: testing-Verifikation direkt nach Merge.
Roadmap impact: „CSP nonce-based script-src hardening (follow-up)"
[ ]→[x]nach testing-Verifikation.Hinweis: Review erstellt von einem AI-Agent (OpenHands) im Auftrag des Users.