ebe1836f7e
- middleware SecurityHeaders (HSTS, CSP, X-Frame-Options, etc.) - trustProxies pour le reverse proxy Nginx Proxy Manager - .env.production.example (APP_DEBUG=false, sessions chiffrees, cookies Secure) - politique de securite SECURITY.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
69 lines
2.4 KiB
PHP
69 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* SecurityHeaders
|
|
* ---------------
|
|
* Ajoute les en-têtes HTTP de sécurité recommandés (OWASP Secure Headers)
|
|
* à toutes les réponses de l'application.
|
|
*
|
|
* Ces en-têtes renforcent la protection contre :
|
|
* - le clickjacking (X-Frame-Options)
|
|
* - le MIME-sniffing (X-Content-Type-Options)
|
|
* - les fuites de référent (Referrer-Policy)
|
|
* - le vol de session sur HTTP (Strict-Transport-Security / HSTS)
|
|
* - certaines injections de contenu (Content-Security-Policy)
|
|
*/
|
|
class SecurityHeaders
|
|
{
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
/** @var Response $response */
|
|
$response = $next($request);
|
|
|
|
// Empêche l'affichage du site dans une iframe (anti-clickjacking)
|
|
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
|
|
|
|
// Empêche le navigateur de "deviner" le type MIME d'un fichier
|
|
$response->headers->set('X-Content-Type-Options', 'nosniff');
|
|
|
|
// Limite les informations de référent envoyées vers l'extérieur
|
|
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
|
|
// Désactive des API navigateur sensibles non utilisées par l'app
|
|
$response->headers->set(
|
|
'Permissions-Policy',
|
|
'geolocation=(), microphone=(), camera=(), payment=()'
|
|
);
|
|
|
|
// HSTS : force le navigateur à n'utiliser que HTTPS pendant 1 an.
|
|
// Uniquement sur connexion sécurisée (le reverse proxy NPM termine le TLS).
|
|
if ($request->isSecure()) {
|
|
$response->headers->set(
|
|
'Strict-Transport-Security',
|
|
'max-age=31536000; includeSubDomains'
|
|
);
|
|
}
|
|
|
|
// Content-Security-Policy : restreint les sources de contenu autorisées.
|
|
// 'unsafe-inline' est toléré pour les styles/scripts Blade + Filament.
|
|
$response->headers->set(
|
|
'Content-Security-Policy',
|
|
"default-src 'self'; "
|
|
."img-src 'self' data: https:; "
|
|
."script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
|
|
."style-src 'self' 'unsafe-inline' https:; "
|
|
."font-src 'self' data: https:; "
|
|
."connect-src 'self'; "
|
|
."frame-ancestors 'self'"
|
|
);
|
|
|
|
return $response;
|
|
}
|
|
}
|