fix(quick-261009-p0m): Schutz-Kopfzeilen in der Weboberfläche, X-Powered-By abgeschaltet

- next.config.ts: nosniff, Referrer-Policy, X-Frame-Options SAMEORIGIN, CSP nur frame-ancestors 'self', Permissions-Policy (Kamera, Mikrofon, Standort, Zahlung, USB), COOP same-origin-allow-popups, poweredByHeader aus
- API: X-Powered-By (Express) in configureHttp abgeschaltet
- Tests: next-config.test.ts, http-setup.spec.ts
- Sicherheitsprotokoll (Zeilen der Außenprüfung), Entwicklungsanleitung, CHANGELOG

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-09 20:29:07 +02:00
parent 2a8a7d4270
commit fceec19ded
8 changed files with 113 additions and 8 deletions
+14
View File
@@ -986,6 +986,20 @@ laufen mit allen Abhängigkeiten und fangen es nicht. Dann gehört das Paket in
Migrationen laufen, die Zeile „Tessera API running“ erscheint) plus die Rauchtests am neu gebauten
Stack – so wie es `checks/fresh-db-start.sh` im Auftrag quick-261009-p0m vormacht.
**Schutz-Kopfzeilen der Weboberfläche (quick-261009-p0m):** `apps/web/next.config.ts` sendet für
alle Pfade `X-Content-Type-Options`, `Referrer-Policy`, `X-Frame-Options: SAMEORIGIN`, eine
Content-Security-Policy, die **nur** `frame-ancestors 'self'` enthält (keine vollständige
Richtlinie – sie braucht eine eigene Prüfung der Inline-Skripte von Next.js), eine
`Permissions-Policy` (Kamera, Mikrofon, Standort, Zahlung, USB gesperrt) und
`Cross-Origin-Opener-Policy: same-origin-allow-popups`; `poweredByHeader` ist aus. **Vor jeder
Erweiterung prüfen:** Die Zwischenablage (`clipboard-write` für „Link kopieren“) darf nicht in der
Permissions-Policy gesperrt werden. Neue Fenster müssen weiter mit `noopener` geöffnet werden;
wer `window.opener` oder `postMessage` zwischen Fenstern braucht, muss die Opener-Richtlinie
überdenken. Eingebettete fremde Seiten (XFrame-Kachel, eigene Module) sind von diesen Kopfzeilen
nicht betroffen. Die API schaltet `X-Powered-By` in `configureHttp` ab (`apps/api/src/http-setup.ts`).
Geprüft werden die Kopfzeilen durch `apps/web/src/next-config.test.ts` und durch die Außenprüfung
(ZAP, siehe „Sicherheitsprüfungen“).
**NestJS-Routenreihenfolge:** NestJS matcht Routen in Deklarationsreihenfolge. Eine statische Route
wie `@Get('source-config')` **muss vor** einem `@Get(':id')`-Platzhalter derselben Klasse stehen —
sonst interpretiert der Platzhalter den literalen Pfadteil als `id` und "beschattet" die statische