isSecure()) { $response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload'); } // X-Frame-Options: SAMEORIGIN (prevents clickjacking by allowing framing only by the same site) $response->headers->set('X-Frame-Options', 'SAMEORIGIN'); // X-Content-Type-Options: nosniff (prevents MIME type sniffing) $response->headers->set('X-Content-Type-Options', 'nosniff'); // Referrer-Policy: stringent check, usually 'strict-origin-when-cross-origin' is good $response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin'); // X-XSS-Protection: 1; mode=block (deprecated but still good for older browsers, some scanners check it) $response->headers->set('X-XSS-Protection', '1; mode=block'); // Permissions-Policy: restrict dangerous features // This is a bit strict, might need adjustment based on site features. // For general sites: geolocation=(), microphone=(), camera=() is often safe. $response->headers->set('Permissions-Policy', 'geolocation=(), microphone=(), camera=()'); // Cross-Origin-Opener-Policy: isolate browsing context from cross-origin documents $response->headers->set('Cross-Origin-Opener-Policy', 'same-origin'); // Content-Security-Policy (CSP) - Start with upgrade-insecure-requests to force HTTPS assets // A full CSP can be tricky and break scripts. 'upgrade-insecure-requests' is safe and good for mixed content. // We can add 'frame-ancestors' here too if X-Frame-Options is ignored by some. // If the user wants A+, a basic CSP is often enough. $csp = "upgrade-insecure-requests; block-all-mixed-content; frame-ancestors 'self';"; $response->headers->set('Content-Security-Policy', $csp); return $response; } }