Security-Hardening Runde 7: Pentest Runde 3 (3 Findings)
KRITISCH – Privilege Escalation: POST /api/developer/setup war ohne Auth erreichbar und konnte developer:access der Admin-Rolle hinzufügen → volle DB-Kontrolle via /developer/*-Routen. Endpoint ersatzlos entfernt; manuelles Setzen geht über prisma/add-developer-permission.ts (CLI). HOCH – Fehlende Migration auf Prod: portalPasswordMustChange war im Code, aber prod-DB hatte die Spalte nicht → jeder Kunden-Login warf Prisma-Schema-Error → DoS. Root Cause: db push statt migrate dev während Entwicklung → kein Migration-File im Repo. Fix: handgenerierte Migration 20260516173552_portal_password_must_change/migration.sql, lokal mit migrate resolve --applied registriert, durch shadow-DB-Reset verifiziert. entrypoint.sh führt migrate deploy bereits aus. MITTEL – Prisma-Internals-Leak im Login-Error: error.message wurde 1:1 an den Client gegeben → bei DB-Schema- Fehlern leakten Tabellen- und Spaltennamen. Whitelist-Filter safeLoginError() in auth.controller.ts: nur 'Ungültige Anmeldedaten' und 'E-Mail und Passwort erforderlich' werden durchgereicht, alles andere wird zu generischem 'Anmeldung fehlgeschlagen' maskiert. Original landet im Server-Log. Live-verifiziert: - POST /api/developer/setup → HTTP 404 - Falsches Customer-PW → 'Ungültige Anmeldedaten' (keine Internals) - Spalte testweise gedropped → 'Anmeldung fehlgeschlagen' (generisch), Original-Message nur im Server-Log - Shadow-DB-Reset + migrate deploy → Spalte korrekt erzeugt Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,37 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **🚨 Pentest Runde 3 – drei Findings gefixt**
|
||||
- **KRITISCH – `POST /api/developer/setup` ohne Auth (Privilege
|
||||
Escalation)**: Endpoint war komplett ohne Authentifizierung
|
||||
erreichbar und konnte der Admin-Rolle die `developer:access`-
|
||||
Permission verleihen → kompletter DB-Zugriff über `/developer/*`.
|
||||
**Fix**: Endpoint ersatzlos gelöscht. Manuelles Setzen geht
|
||||
weiterhin über `prisma/add-developer-permission.ts` (CLI).
|
||||
Live-verifiziert: `POST /api/developer/setup` → HTTP 404.
|
||||
- **HOCH – Customer-Login DoS auf Prod (fehlende Migration)**:
|
||||
`portalPasswordMustChange` war im Code, aber prod-DB kannte die
|
||||
Spalte nicht → Prisma warf bei jedem Kunden-Login. Root Cause:
|
||||
in dieser Session wurde `prisma db push` benutzt (kein Migration-
|
||||
File). **Fix**: handgenerierte Migration
|
||||
`20260516173552_portal_password_must_change/migration.sql` (via
|
||||
`prisma migrate diff` + `migrate resolve --applied`). Verifiziert
|
||||
durch shadow-DB-Reset + `migrate deploy`: Spalte landet korrekt
|
||||
in einer frischen DB. `entrypoint.sh` führt `migrate deploy`
|
||||
beim Container-Start bereits aus → Prod-Restart applied jetzt
|
||||
automatisch.
|
||||
- **MITTEL – Prisma-Internals-Leak im Login-Error-Body**: Bei
|
||||
unerwarteten Fehlern (Schema-Bruch, DB-Down) wurde
|
||||
`error.message` direkt zurückgegeben → Tabellen-/Spaltennamen
|
||||
leakten. **Fix**: Whitelist-Filter `safeLoginError()` in
|
||||
`auth.controller.ts`: nur bekannte Messages
|
||||
(`'Ungültige Anmeldedaten'`, `'E-Mail und Passwort
|
||||
erforderlich'`) werden durchgereicht, alles andere wird zu
|
||||
generischem `'Anmeldung fehlgeschlagen'` und das Original
|
||||
landet im Server-Log. Greift für Mitarbeiter- UND Portal-
|
||||
Login. Live-verifiziert: Spalte testweise gedropped → Client
|
||||
sieht generisch, Server-Log enthält Original.
|
||||
|
||||
- [x] **🔐 Einmalpasswort-Flow für Portal-Credentials**
|
||||
- **Intention**: Wenn wir Zugangsdaten per E-Mail an den Kunden
|
||||
schicken, kennen wir das Passwort als Admin – das ist solange OK,
|
||||
|
||||
Reference in New Issue
Block a user