38c2d82c02
KRITISCH – change-initial-portal-password ohne mustChange-Pflicht-Check: Jeder Portal-User konnte jederzeit sein Passwort ohne Kenntnis des alten ersetzen (XSS-/Token-Hijack-Eskalation). Endpoint war NUR für den OTP-Erst-Login gedacht, prüfte aber das Flag nicht. Fix: Customer laden, portalPasswordMustChange=true erzwingen, sonst 403. NIEDRIG – consentHash leakte über GET /customers/🆔 Hash ist Pseudo-Credential für den öffentlichen Consent-Link. Jetzt in SENSITIVE_CUSTOMER_FIELDS (sanitize.ts) → wird aus jeder customer- Response gestrippt. Wer ihn legitim braucht, holt ihn über /gdpr/customer/:id/consent-status. NIEDRIG – Public consent-grant Response leakte CustomerConsent-Records: POST /api/public/consent/:hash/grant gab volle Records inkl. ipAddress und createdBy (Kunden-Name) zurück. Auf { granted: <count> } reduziert – Frontend liest eh nur success. Live-verifiziert: - Change-Initial ohne Flag → 403; mit Flag → 200; danach Flag=false → erneuter Aufruf 403 - GET /customers/3 → consentHash null, portalPasswordHash null - /gdpr/customer/3/consent-status → consentHash weiterhin sichtbar - Public-Grant-Response: {granted: 4}, keine ipAddress/createdBy Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>