Pentest R92: Strict-400 für accountId auf Vertrags-Endpunkten

R91-Fix war silent-undefined bei invaliden Werten – accountId=abc
auf Vertrags-Endpunkten brach die Mailbox-Isolation (Mails aus
allen Postfächern statt 400). Pentester R92 hat zu Recht
Strict-400 vorgeschlagen.

Helper parsePositiveIntQuery() bekommt { required } option:
- optional (default): fehlend → undefined (kein Filter), invalid → 400
- required: fehlend ODER invalid → 400

Vertrags-Endpunkte (Emails + Folder-Counts) auf required gestellt.
Customer-/Trash-Endpunkte bleiben optional (Cross-Mailbox-View ist
legitim), aber invalid → 400. Frontend hat eh enabled-Guards.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 14:47:42 +02:00
parent 18a2e1173b
commit caa283e66f
2 changed files with 87 additions and 21 deletions
+17
View File
@@ -97,6 +97,23 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
## ✅ Erledigt
- [x] **🔒 Pentest R92 Strict-400 für accountId auf Vertrags-Endpunkten**
- R91-Fix war silent-undefined bei invaliden Werten: `accountId=abc`
auf `GET /contracts/:id/emails` ergab "kein Filter" → Mailbox-
Isolation brach (alle Postfächer sichtbar). Pentester R92: per
Design sind Vertrags-Endpunkte immer pro Postfach, also strict-400.
- Fix: `parsePositiveIntQuery(v, label, res, { required? })`
ersetzt den alten silent-Helper. Modes:
- default (optional): fehlend/leer → `undefined` (kein Filter),
invalid → 400
- `{ required: true }`: fehlend/leer **oder** invalid → 400
- Verteilung:
- Contract-Emails, Contract-Folder-Counts: `{ required: true }`
- Customer-Emails, Trash, Trash-Count: optional (Cross-Mailbox-
View ist legitim), invalid → 400
- Frontend hat schon ein `enabled: !!selectedAccountId`-Guard auf
den Vertrags-Queries kein UX-Bruch.
- [x] **🔒 Pentest R91 NaN-Bypass auf accountId-Query-Param**
- R91.1 (LOW): `accountId=abc``parseInt('abc')` = `NaN` → der
Ternary im Controller gab `NaN` an den Service, `if (NaN)` ist