Pentest R110: Mass-Assignment-Whitelist auf 7 Katalog-Endpunkten

MEDIUM: PUT /api/stressfrei-emails/:id und 6 weitere Update-
Endpunkte (platform, tariff, contractCategory, cancellationPeriod,
contractDuration, email-providers) reichten req.body ungefiltert
an Prisma. Gleiche Bug-Klasse wie das gefixte M1-Finding, sieben
Stellen mehr. Nachgewiesen via provisionError-Feld ausserhalb des
TS-Types.

Fix: sieben Whitelists + pickXxxUpdate()-Helper in sanitize.ts,
in den jeweiligen Controllern eingehängt. Reuse der bewährten
pick()-Infrastruktur (Customer/User seit Runde 7).

EmailProvider bewusst OHNE stripHtmlFromStrings, weil Passwörter
und API-Keys legitim Sonderzeichen enthalten dürfen.

Doku: SECURITY-HARDENING.md § Runde 110 + docs/todo.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 16:16:49 +02:00
co-authored by Claude Opus 4.7
parent dc7dcfb5f3
commit da3ae282fc
10 changed files with 185 additions and 7 deletions
+33
View File
@@ -654,6 +654,39 @@ Modus hängt sowieso an einer schon validierten Email-Stammdate
---
## 🔒 Runde 110 Mass-Assignment-Whitelist auf 7 Katalog-Endpunkten
**Finding (MEDIUM):** Der Pentester hat live nachgewiesen, dass
`PUT /api/stressfrei-emails/:id` beliebige Model-Felder ausserhalb
des TS-Types (z.B. `provisionError`, `isProvisioned`,
`emailPasswordEncrypted`) durchschrieb. Beim „Rumstochern" derselbe
Bug auf sechs weiteren Update-Endpunkten gefunden: `platform`,
`tariff`, `contractCategory`, `cancellationPeriod`,
`contractDuration`, `email-providers`. Gleiche Bug-Klasse wie
das schon gefixte M1-Finding (Settings Mass Assignment), nur an
sieben weiteren Stellen.
Praktische Ausnutzung braucht Staff mit der entsprechenden
Update-Permission kein Portal-User-Vektor, kein Cross-Customer-
Leak. Aber ohne Whitelist könnte ein kompromittierter Staff-Token
z.B. `emailPasswordEncrypted` überschreiben, ohne einen sichtbaren
Audit-Trail durch den regulären Passwort-Set-Flow.
**Fix:** Sieben Field-Whitelists + `pickXxxUpdate()`-Helper in
[`backend/src/utils/sanitize.ts`](../backend/src/utils/sanitize.ts),
eingehängt in die jeweiligen Update-Controller. Nur die vom
Service-Interface deklarierten Felder passieren. Reuse der schon
bewährten `pick()`-Infrastruktur (Customer/User haben denselben
Mechanismus seit Runde 7).
**Ausnahme EmailProvider:** `stripHtmlFromStrings` ist dort AUS.
Grund: das Payload enthält Passwörter und API-Keys, die legitime
Sonderzeichen wie `<`/`>` enthalten dürfen. Whitelist-Filter greift
weiterhin XSS-Risiko minimal, da der Endpunkt admin-only ist und
die Werte in Server-Config-Feldern landen, nicht in User-Notes.
---
## 🔒 Runde 102 Interne Vertragsnummer nachziehen
**Finding (INFO, kein Security-Impact ohne Admin-Login):**