Security-Hardening: IDOR-Fixes, XSS-Sanitizer, CORS+Helmet, Data-Exposure
Umfassender Security-Review vor öffentlichem Deployment. Detaillierter Report in docs/SECURITY-REVIEW.md. 🔴 KRITISCHE FIXES: 1. CORS offen → jetzt nur explizite Origins (via CORS_ORIGINS env), in Production per default komplett aus (gleiche Origin erzwingt Browser). 2. Keine Security-Headers → helmet-Middleware hinzugefügt. X-Frame-Options, X-Content-Type-Options, HSTS, Referrer-Policy, CORP. 3. JWT-Fallback-Secret entfernt. Beim Server-Start wird jetzt geprüft ob JWT_SECRET (min 32 Zeichen) und ENCRYPTION_KEY (exakt 64 Hex) gesetzt sind, sonst Fail-Fast mit klarer Fehlermeldung. 4. IDOR bei 7 Contract-Endpoints. Portal-Kunden mit 'contracts:read' konnten über geratene IDs fremde Daten abrufen (Passwort, SIM-PIN/PUK, Internet-Zugangsdaten, SIP-Credentials, Vertragsdokumente, Rechnungen). Neuer Helper canAccessContract() in utils/accessControl.ts in allen betroffenen Endpoints eingebaut. Prüft Vertrag-Besitzer + Vollmachten. 5. XSS via Email-Body. email.htmlBody wurde ungefiltert via dangerouslySetInnerHTML gerendert. Angreifer konnte Mail mit <script> schicken → Token-Diebstahl aus localStorage. Jetzt mit DOMPurify sanitized: verbietet script/iframe/form/inline-handler, erlaubt normale Formatierung + Bilder. 6. Customer-API leakte sensible Felder: - portalPasswordHash (bcrypt-Hash) - portalPasswordEncrypted (symmetrisch, mit ENCRYPTION_KEY entschlüsselbar) - portalPasswordResetToken (gültig 2h) Neuer Sanitizer in utils/sanitize.ts, angewendet in getCustomer/getCustomers. Admin mit customers:update darf portalPasswordEncrypted sehen (für UI-Anzeige), alle anderen Rollen nicht. 🟡 WICHTIGE FIXES: 7. Portal-JWT-Invalidation nach Passwort-Reset. Neues Feld Customer.portalTokenInvalidatedAt, wird beim Reset auf now() gesetzt. Auth-Middleware prüft Portal-Sessions dagegen. Alte Sessions werden dadurch invalidiert. 8. express.json() mit 5 MB Size-Limit (statt Default 100 KB unklar). Neue Files: - backend/src/utils/accessControl.ts - IDOR-Schutz - backend/src/utils/sanitize.ts - Response-Sanitizer - docs/SECURITY-REVIEW.md - vollständiger Report + Deployment-Checkliste Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,20 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **🛡️ Security-Review + Hardening vor Production-Deployment**
|
||||
- Vollständiger Review aller kritischen Bereiche, dokumentiert in **[docs/SECURITY-REVIEW.md](../docs/SECURITY-REVIEW.md)**
|
||||
- **6 kritische Findings gefixt:**
|
||||
- CORS offen → explizit konfigurierbar über `CORS_ORIGINS`
|
||||
- Helmet (Security-Headers) hinzugefügt
|
||||
- JWT-Fallback-Secret entfernt, ENV-Pflicht-Check beim Start
|
||||
- IDOR bei 7 sensiblen Contract-Endpoints (Portal-Kunden konnten fremde Credentials abrufen)
|
||||
- XSS via Email-Body (DOMPurify als Sanitizer)
|
||||
- Customer-API leakte Passwort-Hashes + Reset-Tokens
|
||||
- **2 wichtige Findings gefixt:**
|
||||
- Portal-JWT-Invalidation nach Passwort-Reset (`Customer.portalTokenInvalidatedAt`)
|
||||
- Body-Size-Limit auf 5 MB
|
||||
- Deployment-Checkliste dokumentiert (neue Secrets generieren, HSTS, DB-User-Rechte, Backup-Cron)
|
||||
|
||||
- [x] **🎉 Version 1.0.0 Feinschliff: Passwort-Reset + Rate-Limiting + Auto-Geburtstagsgrüße**
|
||||
- **Passwort vergessen-Flow** (Login → "Passwort vergessen?" Link)
|
||||
- Email-Reset-Token mit 2h Gültigkeit (kryptografisch sicher: 32 Byte Random)
|
||||
|
||||
Reference in New Issue
Block a user