R192-01: Fehlermeldungen, die fuer Entwickler geschrieben sind

Befund der Pentesterin: PUT /users/:id {"roleIds":{}} gab 400 mit dem
rohen JS-Fehler "object is not iterable". Kein Wipe, keine Eskalation -
dieselbe Familie wie der Prisma-Pfad-Leak aus R190-01.

Zwei Ursachen. Erstens spreizte normalisiereRollenIds die roleIds ohne
Array.isArray-Guard. Zweitens reichte die Fehlerabbildung jede
error.message durch.

Die Unterscheidung laeuft jetzt ueber die Fehlerklasse, nicht ueber eine
Heuristik auf dem Text: Ein blankes Error werfen wir absichtlich und mit
einer Meldung fuer Menschen ("Der letzte Admin kann nicht..."). TypeError
und Verwandte sind Programmierfehler, Prisma-Fehler kommen von aussen -
beides sagt dem Aufrufer nichts Nuetzliches und einem Angreifer zu viel.
Unerwartetes wird 500 statt 400: Ein Eingabefehler-Code waere die naechste
Meldung, die sich falsch ausgibt.

Gegengeprueft, dass mit dem Leck nicht auch das Nuetzliche wegfaellt:
"Rolle kann nicht geloescht werden, da sie 1 Benutzern zugewiesen ist" ->
400, Systemrollen-Sperre -> 403 mit Klartext, Eskalation -> 403 mit den
konkret fehlenden Rechten. {}, "abc", 5, true als roleIds -> 400 "roleIds
muss eine Liste sein", Zustand unveraendert. R190-01/R191-01 gruen.

Offen und groesser als der Befund: Das Muster
`error instanceof Error ? error.message` steht 124-mal in 26
Controller-Dateien. Behoben ist es nur im Benutzer- und Rollenpfad.
Dieselbe Lage wie bei R188 und gehoert genauso zentral geloest.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-09 01:58:51 +02:00
co-authored by Claude Opus 5
parent 702e630ee5
commit 75d009138d
3 changed files with 57 additions and 12 deletions
+29
View File
@@ -100,6 +100,35 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
- [x] **🤐 R192-01: Fehlermeldungen, die für Entwickler geschrieben sind** (2026-09-09)
- Befund der Pentesterin: `PUT /users/:id {"roleIds":{}}` gab 400 mit dem
rohen JS-Fehler `object is not iterable (cannot read property
Symbol(Symbol.iterator))`. Kein Wipe, keine Eskalation — dieselbe Familie
wie der Prisma-Pfad-Leak aus R190-01.
- Zwei Ursachen, beide behoben:
1. `normalisiereRollenIds` spreizte `roleIds` ohne `Array.isArray`-Guard.
2. Die Fehlerabbildung reichte **jede** `error.message` durch.
- Die Unterscheidung läuft jetzt über die **Fehlerklasse**, nicht über eine
Heuristik auf dem Text: Ein blankes `Error` werfen wir absichtlich und mit
einer Meldung für Menschen („Der letzte Admin kann nicht…"). `TypeError`
und Verwandte sind Programmierfehler, Prisma-Fehler kommen von außen —
beides sagt dem Aufrufer nichts Nützliches und einem Angreifer zu viel.
Unerwartetes wird jetzt **500** statt 400: Ein Eingabefehler-Code wäre die
nächste Meldung, die sich falsch ausgibt.
- Gegengeprüft, dass mit dem Leck nicht auch das Nützliche wegfällt:
„Rolle kann nicht gelöscht werden, da sie 1 Benutzern zugewiesen ist" → 400,
Systemrollen-Sperre → 403 mit Klartext, Eskalation → 403 mit den konkret
fehlenden Rechten. `{}`, `"abc"`, `5`, `true` als `roleIds` → 400
„roleIds muss eine Liste sein", Zustand unverändert. R190-01/R191-01
grün.
- **⚠️ Offen, größer als der Befund:** Das Muster
`error instanceof Error ? error.message` steht **124-mal in 26
Controller-Dateien**. Behoben ist es nur im Benutzer-/Rollenpfad. Das ist
dieselbe Lage wie bei R188 (181 ungeprüfte IDs) und gehört genauso
zentral gelöst statt 124-mal einzeln — eigene Runde.
- Dateien: `src/services/rechte.service.ts`, `src/controllers/user.controller.ts`
- [x] **🔗 R191-01: Ein PUT, eine Klammer** (2026-09-09)
- Befund der Pentesterin nach dem R190-01-Fix: Nur der Rollentausch lag in
der Transaktion, die drei Haken (DSGVO/Developer/Audit-Betrieb) liefen