security: Header-Hygiene-Runde 11 (Pentest-Cleanup)
Behebt die drei behebbaren Klassen aus dem ZAP-/Nikto-Audit vom 2026-05-16:
1. HSTS-Doppel-Header (18 Findings):
Helmet's strictTransportSecurity komplett deaktiviert. Der Nginx Proxy
Manager vor der CRM-VM setzt HSTS bereits (Force SSL + HSTS Enabled +
HSTS Sub-domains via UI). Doppelter Header verletzt RFC 6797.
2. Cache-Control (~10 Findings):
- /api/* → 'no-store' (sensible JSON-Daten)
- SPA-HTML (/, /robots.txt, /sitemap.xml, /vite.svg) → 'no-store,
must-revalidate' (sonst hängt Browser nach Deploy an alter index.html
mit alten Asset-Hashes fest)
- /assets/*.{js,css} (Vite-Build mit Content-Hash) → 'public,
max-age=31536000, immutable'
3. CSP No-Fallback-Direktiven (2 Findings):
worker-src, manifest-src, media-src jetzt explizit auf 'self'. ZAP
meckert sonst "Failure to Define Directive with No Fallback".
Bewusst NICHT gefixt: style-src 'unsafe-inline' (11 Findings). Tailwind +
React (style={{…}}) erzeugen viele inline-styles; nonce-/hash-basierte CSP
wäre ein größerer Build- und Code-Refactor mit eher kosmetischem Gewinn,
da der primäre XSS-Schutz weiterhin via script-src 'self' und Input-
Sanitization greift.
Live verifiziert (Headers via curl gegen HTTPS_ENABLED=true Container):
- / → 'no-store, must-revalidate', kein HSTS
- /assets/index-*.js → 'public, max-age=31536000, immutable', kein HSTS
- /api/health → 'no-store', kein HSTS
- SPA-Fallback (/sitemap.xml, /robots.txt) → 'no-store, must-revalidate'
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,25 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **🛡️ Pentest-Hardening-Runde 11: Header-Hygiene**
|
||||
- **HSTS-Doppel-Header** (18× low im Audit): Helmet's
|
||||
`Strict-Transport-Security` komplett deaktiviert. Der Nginx Proxy Manager
|
||||
vor der CRM-VM setzt HSTS bereits, doppelter Header verletzte RFC 6797.
|
||||
- **Cache-Control** (≥10× info im Audit):
|
||||
`/api/*` bekommt `no-store` (sensible JSON-Daten),
|
||||
SPA-HTML (`/`, `/sitemap.xml`, `/robots.txt`, `/vite.svg`) bekommt
|
||||
`no-store, must-revalidate` (sonst hängt Browser an alter index.html
|
||||
fest nach Deploy),
|
||||
`/assets/*` (Vite-Build mit Content-Hash im Filename) bekommt
|
||||
`public, max-age=31536000, immutable`.
|
||||
- **CSP No-Fallback-Direktiven** (2× medium): `worker-src`, `manifest-src`,
|
||||
`media-src` explizit auf `'self'` – ZAP markiert sonst „Failure to
|
||||
Define Directive with No Fallback".
|
||||
- Bewusst NICHT angefasst: `style-src 'unsafe-inline'` (Tailwind/React-
|
||||
inline-styles, kompletter Refactor unverhältnismäßig).
|
||||
- Live verifiziert: Headers für `/`, `/api/*`, `/assets/*.js` und SPA-
|
||||
Fallback-Pfade alle wie erwartet.
|
||||
|
||||
- [x] **🐛 PDF-Vorschau im PDF-Template-Editor lädt nicht**
|
||||
- CSP-Direktive `frame-ancestors 'none'` blockte ALLE iframe-Embeddings
|
||||
der eigenen Resourcen, auch same-origin – Browser zeigte je nach
|
||||
|
||||
Reference in New Issue
Block a user