Mass-Assignment-Schutz: Nested-Vertragsdetails (Pentest R162-01)
createContract/updateContract spreadeten energyDetails/tvDetails/
carInsuranceDetails/mobileDetails (via ...mobileData) roh an Prisma.
Injizierte id/contractId konnten ein Detail-Objekt auf einen Fremdvertrag
reparenten oder den PK frei setzen (stilles 200 statt 400) - MEDIUM
(Integritaet; kein Cross-Tenant, staff-only, Portal 403).
Fix: Feld-Whitelists (pickEnergyScalars/pickMobileScalars/pickTvScalars/
pickCarInsuranceScalars, analog R158) an allen Spread-Stellen in create+update.
internet war bereits explizit (preparedInternetData) - safe. Whitelists
programmatisch gegen die DB-Spalten abgeglichen (minus id/contractId/
verschluesselt) - alle Diffs leer.
Verifiziert: energyDetails{basePrice:99.99, id:999999, contractId:fremd}
-> basePrice aktualisiert, ecd.id + contractId unveraendert (kein Reparenting).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,19 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **🔒 Mass-Assignment-Schutz: Nested-Vertragsdetails (Pentest R162-01)** (2026-08-18)
|
||||
- `createContract`/`updateContract` spreadeten `energyDetails`/`tvDetails`/
|
||||
`carInsuranceDetails`/`mobileDetails` (via `...mobileData`) roh an Prisma →
|
||||
injizierte `id`/`contractId` konnten ein Detail-Objekt **reparenten** (auf
|
||||
Fremdvertrag umhängen) oder den **PK frei setzen** (stilles 200 statt 400).
|
||||
MEDIUM (Integrität; kein Cross-Tenant, staff-only, Portal 403).
|
||||
- **Fix:** Feld-Whitelists (`pickEnergyScalars`/`pickMobileScalars`/`pickTvScalars`/
|
||||
`pickCarInsuranceScalars`, analog R158) an allen Spread-Stellen. `internet`
|
||||
war bereits explizit (safe). Whitelists programmatisch gegen die DB-Spalten
|
||||
abgeglichen (minus id/contractId/verschlüsselt) – alle Diffs leer.
|
||||
- Verifiziert: `energyDetails:{basePrice:99.99, id:999999, contractId:fremd}` →
|
||||
basePrice aktualisiert, ecd.id + contractId **unverändert** (kein Reparenting).
|
||||
|
||||
- [x] **📋 Aufgaben ohne Kunde/Vertrag anlegbar** (2026-08-18)
|
||||
- `ContractTask.contractId` nullable (Migration `20260818110000`). Neuer Endpoint
|
||||
`POST /tasks` (staff-only, `contracts:update`) für allgemeine Aufgaben ohne
|
||||
|
||||
Reference in New Issue
Block a user