Refresh-Fehlschlag: Detection-Gap geschlossen (Pentest R164-01)
Fehlgeschlagener /auth/refresh (Replay/Brute-Force auf geraubte Refresh-Tokens) wurde als TOKEN_REFRESH/LOW geloggt und entging der Alarmierung - ein Angreifer konnte von /login auf /refresh ausweichen, um unter der LOGIN_FAILED-Schwelle zu bleiben. Audit-Actions speisen die Alert-Engine nicht (die zaehlt SecurityEvent via emit). Fix daher an zwei Ebenen: - Detection: refresh()-Catch emittiert TOKEN_REJECTED -> greift die bestehende Schwelle (>=3 TOKEN_REJECTED/5min/IP -> CRITICAL). Severity wie Access-Token: abgelaufen/revoked = LOW (kein Sofort-Alert), ungueltige Signatur/Manipulation = HIGH. auth.service reicht dafuer err.code REFRESH_EXPIRED/REFRESH_INVALID durch. "Kein Cookie" emittiert bewusst nicht (normaler Erstbesuch). - Audit-Triage: fehlgeschlagener Refresh -> Sensitivitaet HIGH statt LOW + Label "Token-Refresh abgelehnt". Action bleibt TOKEN_REFRESH (semantisch ein Refresh, kein Login). Verifiziert: tsx-Test abgelaufen->LOW, manipuliert/garbage->HIGH; tsc gruen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,30 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **🛡️ Refresh-Fehlschlag: Detection-Gap geschlossen (Pentest R164-01)** (2026-08-18)
|
||||
- Folgefund zum Entrauschen: `determineAction` gab `/auth/refresh` bedingungslos
|
||||
`TOKEN_REFRESH`/LOW → ein **fehlgeschlagener** Refresh (Replay/Brute-Force auf
|
||||
geraubte/geratene Refresh-Tokens) rutschte als LOW durch und entging der
|
||||
Alarmierung (Angreifer weicht von `/login` auf `/refresh` aus, um unter
|
||||
CRITICAL zu bleiben).
|
||||
- **Wichtig:** Audit-Actions speisen die Alert-Engine NICHT (die zählt
|
||||
`SecurityEvent`-Zeilen via `emit()`). Der Tester-Minimalvorschlag (Action →
|
||||
`LOGIN_FAILED`) hätte also keinen Alert ausgelöst. Echter Fix an 2 Ebenen:
|
||||
- **Detection:** `refresh()`-Catch emittiert jetzt `TOKEN_REJECTED` →
|
||||
greift die bestehende Schwelle `≥3 TOKEN_REJECTED/5min/IP → CRITICAL`
|
||||
(securityAlert.service, kein Severity-Filter). Severity wie Access-Token:
|
||||
abgelaufen/revoked → LOW (benigne, kein Sofort-Alert), ungültige
|
||||
Signatur/Manipulation → HIGH (Sofort-Alert). `auth.service` reicht dafür
|
||||
`err.code` REFRESH_EXPIRED/REFRESH_INVALID durch. „Kein Cookie" emittiert
|
||||
NICHT (normaler Erstbesuch).
|
||||
- **Audit-Triage:** fehlgeschlagener Refresh → Sensitivität HIGH statt LOW +
|
||||
Label „Token-Refresh abgelehnt (ungültig/abgelaufen)". Action bleibt
|
||||
bewusst `TOKEN_REFRESH` (semantisch ein Refresh, kein Login).
|
||||
- Verifiziert: tsx-Test — abgelaufen→LOW, manipuliert/garbage→HIGH; `tsc` grün.
|
||||
- Nebenbefund R164-02 (pre-existing, kein Commit von uns): Refresh-Rotation
|
||||
bietet keinen Replay-Schutz (alter Token bis exp gültig), aber fail-closed
|
||||
nach Logout. Ggf. später: Refresh-Token-Jti-Blacklist / One-Time-Use.
|
||||
|
||||
- [x] **🔇 Audit-Log: stiller Token-Refresh entrauscht (`TOKEN_REFRESH`)** (2026-08-18)
|
||||
- Automatische `POST /auth/refresh`-Aufrufe (Interceptor bei 401 / nach
|
||||
Seiten-Reload, da Access-Token nur im Speicher) wurden als `CREATE` /
|
||||
|
||||
Reference in New Issue
Block a user