/** * Globale Security-Header für Nitro (Nuxt 3). * * Apache setzt ggf. bereits Header – diese Middleware dient als "Default", * damit die App auch ohne Reverse-Proxy sauber gehärtet ist. * * CSP ist optional und sollte zuerst im Report-Only Modus getestet werden. * Siehe ENV: * - CSP_ENABLED=true|false * - CSP_REPORT_ONLY=true|false * - CSP_VALUE="..." */ export default defineEventHandler((event) => { // Grundsätzlich sinnvolle Header setHeader(event, 'X-Content-Type-Options', 'nosniff') setHeader(event, 'Referrer-Policy', 'strict-origin-when-cross-origin') setHeader(event, 'Permissions-Policy', 'geolocation=(), microphone=(), camera=()') // X-Frame-Options: SAMEORIGIN (DENY wäre strenger, verhindert aber iFrames komplett) setHeader(event, 'X-Frame-Options', 'SAMEORIGIN') // Legacy-Header (optional; moderne Browser verlassen sich primär auf CSP) setHeader(event, 'X-XSS-Protection', '0') // Optional: CSP const cspEnabled = (process.env.CSP_ENABLED || '').toLowerCase() === 'true' if (cspEnabled) { const reportOnly = (process.env.CSP_REPORT_ONLY || 'true').toLowerCase() !== 'false' const cspValue = process.env.CSP_VALUE || [ "default-src 'self'", "base-uri 'self'", "object-src 'none'", "frame-ancestors 'self'", // Nuxt lädt Fonts ggf. von Google (siehe nuxt.config.js) "font-src 'self' https://fonts.gstatic.com data:", "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com", // Script: Nuxt kann in Dev eval nutzen; diese CSP ist primär für Produktion gedacht. "script-src 'self'", "img-src 'self' data: blob:", "connect-src 'self'" ].join('; ') setHeader(event, reportOnly ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy', cspValue) } })