fix: Portal-Passwörter im Vertrag wurden mutiliert

Folgefehler aus Pentest 31.1: die rekursive sanitizeContractBody()
lief auch über portalPassword. Passwörter mit HTML-Pattern
("Pass<TAG>word!" → "Password!") oder URI-Schema-Prefix
("data:secret" → "blocked:secret") wurden vom stripHtml-Strip
zerstört, bevor die Service-Schicht sie verschlüsseln konnte.

Fix: PASSTHROUGH_KEYS = {portalPassword, password}. Beim Walk
werden String-Werte unter diesen Keys NICHT gefiltert. Passwort
wird sowieso encrypt()-verschlüsselt in die DB geschrieben und
niemals als HTML ausgegeben – kein XSS-Risk.

Live-verifiziert:
- PUT portalPassword="MyP@ss<word>123!&data:foo"
  → GET /password decrypt liefert byte-identischen Wert
- PUT providerName="<script>...EvilProvider" → DB: "EvilProvider"
  (XSS-Schutz weiter aktiv)
- PUT portalUsername="u<test>" → DB: "u" (Plain-Text-User wird
  weiter gestrippt, ist kein Passwort)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-27 02:05:26 +02:00
parent aa0900410b
commit f41d1843e4
2 changed files with 32 additions and 4 deletions
+15
View File
@@ -120,6 +120,21 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
- **Live-verifiziert**: 4867 Datensätze + 1 Datei in 13.2s
wiederhergestellt, Log-Modal zeigt den vollständigen Verlauf.
- [x] **🐛 Bugfix: Portal-Passwörter in Verträgen wurden mutiliert**
- Folgefehler aus Pentest 31.1 (Stored-XSS-Strip): die rekursive
`sanitizeContractBody`-Funktion lief auch über `portalPassword`.
Passwörter mit HTML-Pattern (`Pass<TAG>word!``Password!`) oder
URI-Schema-Prefix (`data:secret``blocked:secret`) wurden
irreparabel zerstört.
- Fix: `PASSTHROUGH_KEYS = {'portalPassword', 'password'}` beim
Walk werden String-Werte unter diesen Keys NICHT durch
`stripHtml` geschickt. PW wird sowieso `encrypt()`-verschlüsselt
persistiert und niemals als HTML ausgegeben → kein XSS-Risk.
- Live-verifiziert: PW `MyP@ss<word>123!&data:foo` → byte-genau im
GET-Decrypt-Endpoint zurück. `providerName: <script>…` → weiter
auf `EvilProvider` gestrippt. `portalUsername: u<test>` → weiter
auf `u` gestrippt.
- [x] **🛡️ Pentest 2026-05-24 Pen-31-Befunde (2× MEDIUM)**
- **31.1 Stored XSS in Vertragsfeldern**: `providerName`, `tariffName`,
`priceFirst12Months`, `priceFrom13Months`, `priceAfter24Months`