Pentest 2026-05-20 LOW/INFO Sammelfix

27.1 Path-Traversal-Strings in DB:
- cleanupConsents validierte documentPath zuvor nur per stripHtml,
  ließ "../../../etc/passwd" durch. Neuer isValidDocumentPath-Check
  akzeptiert nur "/uploads/<safe>", alles andere → NULL.
- cleanupDocumentPaths scannt fünf weitere Tabellen (BankCard,
  IdentityDocument, Invoice, RepresentativeAuthorization nullable;
  ContractDocument NOT NULL → nur Report).

Orphaned User:
- reportOrphanedUsers warnt beim Container-Start vor User ohne
  Rollenzuordnung (im Permission-System unsichtbar). Löschen nicht
  automatisch wegen False-Positive-Risiko.

Seed-PW-Policy:
- generateInitialPassword() nutzte Math.random() (vorhersagbar).
  Jetzt crypto.randomInt() für Pick + Fisher-Yates-Shuffle.

PUT /users/:id mit permissions / password:
- Vorher silent-drop durch Whitelist + HTTP 200, Caller glaubte
  faelschlich, Werte waeren uebernommen. Jetzt HTTP 400 mit
  konkreter Hilfe-Message.

/api/health ohne Auth:
- Pentest-Befund INFO: bewusst so, Container-Healthcheck und
  Reverse-Proxy pingen ohne Bearer-Token. Antwort liefert nur
  {status,timestamp} – keine Version, kein DB-Status, kein
  Info-Leak. Comment im Code dokumentiert die Entscheidung.

Live-verifiziert auf dev: alle fuenf Findings durchgetestet,
jeweils mit dirty Input → erwartete Sanitization/Antwort.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 07:49:06 +02:00
parent adc3b70492
commit 8e48d3b432
5 changed files with 184 additions and 13 deletions
+33
View File
@@ -120,6 +120,39 @@ 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] **🧹 Pentest 2026-05-20 LOW/INFO-Sammelfix**
- **27.1 Path-Traversal-Strings in DB**: `cleanupConsents` validierte
`documentPath` zuvor nur per stripHtml, was `../../../etc/passwd`
durchließ (kein File-Read, aber dreckige Datenbasis). Neuer
`isValidDocumentPath`-Check akzeptiert nur `/?uploads/<safe>`,
alles andere wird auf `NULL` gesetzt.
- Generischer `cleanupDocumentPaths`-Pass über die fünf weiteren
Tabellen mit `documentPath` (BankCard, IdentityDocument, Invoice,
RepresentativeAuthorization als nullable; ContractDocument
NOT NULL → wird nur berichtet, manuell entscheiden).
- **Orphaned User**: Neuer Report-Step `reportOrphanedUsers` warnt
beim Container-Start vor User ohne Rollenzuordnung (= im
Permission-System unsichtbar). Löschen tut das Skript nicht
(false-positive-Risiko bei legitimen Spezial-Usern).
- **Seed-PW-Policy**: `generateInitialPassword()` nutzte
`Math.random()` (vorhersagbar). Jetzt `crypto.randomInt()` für
Pick + Shuffle, 28 Zeichen aus 4 Klassen.
- **`PUT /users/:id` mit `permissions` / `password`**: vorher
silent-drop durch Whitelist + HTTP 200. Jetzt explizit HTTP 400
mit Hinweis auf den dedizierten `/password`-Endpoint bzw. die
Role-Steuerung. Gleicher Pattern wie `PUT /portal` für password.
- **`/api/health` ohne Auth**: BEWUSST so Container-Healthcheck +
Reverse-Proxy pingen ohne Bearer-Token. Antwort liefert nur
`{status,timestamp}` keine Version, kein DB-Status, kein
Hostname → kein Info-Leak. Kommentar im Code dokumentiert die
Entscheidung.
- **Live-verifiziert** auf dev:
- CustomerConsent.documentPath=`../../../etc/passwd` → NULL
- PUT /users mit `permissions` → 400 mit klarer Message
- PUT /users mit `password` → 400 mit Hinweis auf /password
- Orphan-User angelegt → vom Cleanup-Lauf gemeldet
- `crypto.randomInt`-Pfad rauscht durch ohne Fehler
- [x] **🛡️ Pentest 2026-05-20 MEDIUM+LOW: Consent + URI-Sanitization**
- **MEDIUM Consent-Mass-Assignment**: PUT `/api/gdpr/customer/:id/consents/:type`
nahm `source`, `documentPath`, `version` ungefiltert aus dem Body