Pentest 2026-05-20 Pen-30-Befunde (MEDIUM+INFO)
30.13 MIME-Extension-XSS (MEDIUM): GET /api/files/download lieferte hochgeladene Dateien via res.sendFile() aus. Da multer nur den client-gemeldeten MIME prueft, konnte eine als application/pdf deklarierte .html-Datei auf Disk landen – Express liest beim Senden den Content-Type aus der Extension (text/html), Browser haette gerendert → Stored XSS. Fix: Content-Disposition: attachment + safe filename. Browser laedt jetzt herunter statt zu rendern, egal welcher Content-Type. UX-Cost ist gering (PDF-Preview offnet halt aus dem Download-Ordner). X-Content-Type-Options: nosniff bleibt zusaetzlich gesetzt. 30.14 SSRF Private-IP-Block opt-in (INFO): ssrfGuard erlaubte private IPs (127/10/172.16/192.168) bewusst, weil On-Prem-Setups Plesk/Dovecot/Postfix lokal laufen lassen. Fuer Cloud-Deployments ist das ein SSRF-Vektor. Neuer Env-Flag SSRF_BLOCK_PRIVATE_IPS=true erweitert die Block-Liste um alle privaten Ranges + ::1 + fc00::/7 + IPv4-mapped + localhost/ ip6-localhost. Default off (on-prem-kompatibel). Live-verifiziert auf dev: - Download-Header: Content-Disposition: attachment + safe filename - Default: 127.0.0.1/10.x/192.168.x/localhost durchgelassen, 169.254.169.254 (Cloud-Metadata) weiter geblockt - SSRF_BLOCK_PRIVATE_IPS=true: alle privaten Ranges geblockt, 8.8.8.8 (legitim) durchgelassen Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,35 @@ 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 Pen-30-Befunde (MEDIUM+INFO)**
|
||||
- **30.13 MIME-Extension-XSS** (MEDIUM): `GET /api/files/download`
|
||||
lieferte hochgeladene Dateien via `res.sendFile` aus. Da multer
|
||||
nur den client-gemeldeten MIME prüft, konnte eine als
|
||||
`application/pdf` deklarierte `.html`-Datei auf Disk landen –
|
||||
Express bestimmt beim Senden den Content-Type aus der Extension
|
||||
(`.html` → `text/html`) und der Browser hätte gerendert. Stored
|
||||
XSS für eingeloggte Empfänger. Fix: `Content-Disposition:
|
||||
attachment; filename=<safe>` + bestehendes `X-Content-Type-
|
||||
Options: nosniff`. Browser lädt jetzt herunter statt zu rendern,
|
||||
selbst wenn der Type stimmt. Filename wird auf
|
||||
`[A-Za-z0-9._-]` gesäubert.
|
||||
- **30.14 SSRF Private-IP-Block opt-in** (INFO): Neuer Env-Flag
|
||||
`SSRF_BLOCK_PRIVATE_IPS=true` erweitert die SSRF-Block-Liste auf
|
||||
127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, ::1,
|
||||
fc00::/7 + IPv4-mapped Varianten + Hostnamen "localhost"/
|
||||
"ip6-localhost". Default off, damit On-Prem-Installationen
|
||||
(Plesk/Dovecot auf 127.0.0.1) nicht brechen. Cloud-Deployments
|
||||
setzen den Flag.
|
||||
- **Live-verifiziert** auf dev:
|
||||
- Upload + Download: Header zeigt
|
||||
`Content-Disposition: attachment; filename="…"` +
|
||||
`X-Content-Type-Options: nosniff`
|
||||
- Default-ssrfGuard: 127.0.0.1 / 10.x / 192.168.x / localhost → false
|
||||
(durchgelassen für on-prem); 169.254.169.254 → true (Cloud-
|
||||
Metadata weiter geblockt)
|
||||
- Mit `SSRF_BLOCK_PRIVATE_IPS=true`: alle privaten Ranges → true;
|
||||
8.8.8.8 (legit public) → false
|
||||
|
||||
- [x] **🛡️ Pentest 2026-05-20 Pen-29-Befunde (LOW/INFO)**
|
||||
- **28.1 Restarbeit**: `DANGEROUS_URI_SCHEMES` jetzt vollständig –
|
||||
`blob:`, `about:`, `ws:`, `wss:`, `ldap:`, `dict:` ergänzt. Bewusst
|
||||
|
||||
Reference in New Issue
Block a user