From 077e5225546a7c3e75619f8ffd7e68a410824d2b Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Thu, 8 Oct 2026 13:02:49 +0000 Subject: [PATCH] dev: Phase 4 im Sicherheits-Entwicklungsplan auf Stand v1.5.0/v1.6.0 Co-Authored-By: Claude Opus 5.5 --- .../ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dev/sicherheit/ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md b/dev/sicherheit/ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md index 45198d43..72122556 100644 --- a/dev/sicherheit/ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md +++ b/dev/sicherheit/ENTWICKLUNGSPLAN-SICHERHEIT-2026-10-07.md @@ -2,7 +2,7 @@ **Grundlage:** [SICHERHEITSAUDIT-2026-10-07.md](SICHERHEITSAUDIT-2026-10-07.md), Repository-Stand `2215826` -**Stand:** 08.10.2026 – Phasen 1–3 und Entscheidung 5 (Passkeys, Pflicht-Zweitfaktor für Admins) live seit `v1.4.0` (07.10.2026), Hotfix `v1.4.1`; Abgleich der Firmenrechte ausgeführt (19.607 → 19.316, Wiederholung stabil). Übrige Phase 4 offen +**Stand:** 08.10.2026 – Phasen 1–3 und Entscheidung 5 (Passkeys, Pflicht-Zweitfaktor für Admins) live seit `v1.4.0` (07.10.2026), Hotfix `v1.4.1`; Abgleich der Firmenrechte ausgeführt (19.607 → 19.316, Wiederholung stabil). API-Zugang an Buchung, Proxy und HSTS live seit `v1.5.0` (08.10.2026); restliche Phase 4 umgesetzt für `v1.6.0` (Abschnitt 6) **Ausführung:** Befehle direkt im Dev-Container (`php artisan …`, ohne Sail – siehe `.ai/rules/general.md`) @@ -113,7 +113,7 @@ Alles zusammen geht als ein Release raus. Vorgeschlagen ist `v1.4.0`: neue Funkt **Offen geblieben:** -- **Phase 4 (Härtung)** ohne Entscheidung 5: npm-Advisories, Proxy, HSTS, Passwortregeln, dauerhafte Widerrufsmarke, API-Token-Ablauf, Login-Limit, CSP. +- **Phase 4 (Härtung):** inzwischen erledigt, Stand in Abschnitt 6. ## 1. Nachprüfung des Audits @@ -284,15 +284,15 @@ Er wird von S-05 Teil B und von S-06 gebraucht, deshalb einmal sauber bauen: | Thema | Maßnahme | Aufwand | | --- | --- | --- | -| npm-Advisories | `npm update shell-quote source-map-js` (oder `overrides` in `package.json`), danach `npm run build` und `npm audit --omit=dev`. | 15 min | -| Proxy | Auf dem Server prüfen, dass der App-Container keinen veröffentlichten Port hat und nur über Traefik erreichbar ist. Dann `trustProxies(at: …)` auf das Docker-Netz begrenzen. | 30 min | -| HSTS | Prüfen, ob Traefik HSTS setzt (`curl -sI https://pressekonto.de`). Falls nicht, dort ergänzen. | 15 min | +| ~~npm-Advisories~~ | ✅ `v1.6.0`: `source-map-js` 1.2.2, `shell-quote` per `overrides` auf ^1.11.0 (1.12.0) — `concurrently` legt 1.9.0 fest, `npm audit fix` stufte nur herab. `npm audit`: 0. | – | +| ~~Proxy~~ | ✅ `v1.5.0`: Live hat keinen Proxy (nginx direkt). `config/trustedproxy.php`: lokal `*` (Traefik), sonst keinem; ein CDN später über `TRUSTED_PROXIES`. | – | +| ~~HSTS~~ | ✅ `v1.5.0`: `SecurityHeaders` setzt `max-age=31536000` in Produktion auf HTTPS (ohne `includeSubDomains`/`preload`). | – | | ~~Pflicht-2FA Admins~~ | ✅ Umgesetzt als Entscheidung 5 (Passkeys oder App, Super-Admins und Admins), siehe Abschnitt 0. | – | -| Passwortregeln | In `AppServiceProvider` `Password::defaults(fn () => Password::min(12)->uncompromised())` nur in Produktion setzen. `uncompromised()` fragt HIBP per k-Anonymität ab. | 1 h | -| Widerruf dauerhaft | Die Marke aus `SessionRevocation` zusätzlich als Spalte `users.sessions_revoked_at` speichern, damit ein `cache:clear` widerrufene Sitzungen nicht wieder freigibt. `users` hat FULLTEXT, ist aber mit 25 MB klein (siehe CLAUDE.md). | 2 h | -| API-Tokens | Optionales Ablaufdatum bei der Erzeugung und Anzeige „zuletzt verwendet“. Kein globales `expiration`, sonst brechen Integrationen. | 2 h | -| Login-Limit | Zusätzliches IP-weites Limit (z. B. 50/min), gegen Password-Spraying. | 1 h | -| CSP | `Content-Security-Policy-Report-Only` passend zu Livewire/Alpine einführen, Verstöße in GlitchTip sammeln und später scharf schalten. | 1 Tag | +| ~~Passwortregeln~~ | ✅ `v1.6.0`: mindestens 12 Zeichen für neue und geänderte Passwörter, in Produktion zusätzlich `uncompromised()`. Bestehende Passwörter bleiben gültig. | – | +| ~~Widerruf dauerhaft~~ | ✅ `v1.6.0`: Spalte `users.sessions_revoked_at_ms` (Millisekunden wie der Session-Stempel), Middleware liest sie am geladenen User. Übergangsweise zählt die alte Cache-Marke mit — im Release danach entfernen. Zusätzlich Knopf „Andere Geräte abmelden“ auf der Sicherheitsseite. | – | +| ~~API-Tokens~~ | ✅ `v1.5.0`: optionales Ablaufdatum, Zugang endet mit der Buchung (403), `sanctum:prune-expired` täglich. | – | +| ~~Login-Limit~~ | ✅ `v1.6.0`: `LoginIpThrottle`, 20 Fehlversuche je IP in 15 Minuten über alle Konten; zählt per `Failed`-Event für Livewire-Login und `POST /login`. | – | +| CSP (Stufe 1) | ✅ `v1.6.0`: `Content-Security-Policy-Report-Only` in Produktion, Meldungen über `/csp-report` nach `storage/logs/csp-*.log` (je Meldung höchstens einmal pro Stunde, ohne Query und Tokens). **Offen:** nach einigen Tagen auswerten, Liste ergänzen, dann scharf schalten; `'unsafe-inline'`/`'unsafe-eval'` bleiben bis zu einer Nonce-Lösung. | später | ## 7. Ablauf und Abnahme