security: Content-Security-Policy aktivieren (Pentest-Finding)
Bug: Stage-1-Kommentar behauptete fälschlicherweise, das Frontend setze eine CSP via meta-Tag – passierte nie. Helmet-CSP war auf false, kein CSP-Header im Response. Pentest-Tool hat das richtig moniert. Fix: Helmet-CSP eingeschaltet mit SPA-tauglichen directives: default-src 'self' script-src 'self' (Vite baut Module-Scripts zu separaten Files) style-src 'self' 'unsafe-inline' (Tailwind/inline-styles) img-src self/data/blob (base64-Avatare, blob-PDFs) font-src self/data connect-src 'self' (API only) frame-ancestors 'none' (Clickjacking-Schutz, ersetzt X-Frame-Options) object-src 'none' (kein Flash/<object>) base-uri 'self' form-action 'self' upgrade-insecure-requests Live-verifiziert: - Frontend index.html hat keine inline-scripts und keine externen Resources (Vite-Production-Build) → CSP bricht nichts. - Header gesetzt: Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; ... Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+32
-3
@@ -81,11 +81,40 @@ app.set('trust proxy', 'loopback');
|
||||
|
||||
// ==================== SECURITY MIDDLEWARE ====================
|
||||
|
||||
// HTTP Security Headers (X-Frame-Options, X-Content-Type-Options, HSTS, etc.)
|
||||
// HTTP Security Headers (X-Frame-Options, X-Content-Type-Options, HSTS, CSP, ...)
|
||||
//
|
||||
// CSP ist konservativ aber SPA-tauglich:
|
||||
// - script-src 'self' → keine externen Skripte, keine inline-Scripts
|
||||
// (Vite baut Module-Skripte zu separaten Files,
|
||||
// die sind 'self')
|
||||
// - style-src 'self' 'unsafe-inline' → Tailwind/inline-Styles brauchen das
|
||||
// (sicheres Trade-off; XSS via CSS ist
|
||||
// marginal vs Lock-Out gegen die UI)
|
||||
// - img-src self/data/blob → base64-Avatare + blob-URLs für PDFs/Downloads
|
||||
// - font-src self/data → eingebettete Fonts
|
||||
// - connect-src 'self' → API + WebSocket nur zur eigenen Origin
|
||||
// - frame-ancestors 'none' → Clickjacking-Schutz (ersetzt X-Frame-Options)
|
||||
// - object-src 'none' → keine Flash/<object>/<embed>-Embeds
|
||||
// - base-uri 'self' → keine <base>-Hijacking-Tricks
|
||||
// - form-action 'self' → POST-Targets nur auf eigene Origin
|
||||
app.use(
|
||||
helmet({
|
||||
// CSP ausschalten – wird bei SPA schwierig, frontend setzt eigene CSP via meta
|
||||
contentSecurityPolicy: false,
|
||||
contentSecurityPolicy: {
|
||||
useDefaults: true,
|
||||
directives: {
|
||||
'default-src': ["'self'"],
|
||||
'script-src': ["'self'"],
|
||||
'style-src': ["'self'", "'unsafe-inline'"],
|
||||
'img-src': ["'self'", 'data:', 'blob:'],
|
||||
'font-src': ["'self'", 'data:'],
|
||||
'connect-src': ["'self'"],
|
||||
'frame-ancestors': ["'none'"],
|
||||
'object-src': ["'none'"],
|
||||
'base-uri': ["'self'"],
|
||||
'form-action': ["'self'"],
|
||||
'upgrade-insecure-requests': [], // wenn HTTPS verfügbar, dann erzwingen
|
||||
},
|
||||
},
|
||||
// Cross-Origin-Resource-Policy: "same-site" für SPA mit gleicher Origin
|
||||
crossOriginResourcePolicy: { policy: 'same-site' },
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user