headers->has('Content-Security-Policy')) { $reponse->headers->set('Content-Security-Policy', $this->politique($request)); } return $reponse; } private function politique(Request $request): string { $communes = [ 'default-src' => "'self'", 'img-src' => "'self' data:", 'font-src' => "'self' https://fonts.gstatic.com", 'object-src' => "'none'", 'base-uri' => "'self'", 'form-action' => "'self'", 'frame-ancestors' => "'none'", 'report-uri' => '/csp-rapport', ]; $directives = $this->estApplication($request) ? [ 'script-src' => "'self' 'nonce-".Vite::cspNonce()."'", // Attributs style= présents dans le gabarit commun : sans // risque d'exécution de code, tolérés. 'style-src' => "'self' 'unsafe-inline' https://fonts.googleapis.com", 'connect-src' => "'self' wss://{$request->getHost()}", ] : [ 'script-src' => "'self' 'unsafe-inline' https://cdn.jsdelivr.net https://cdn.tailwindcss.com", 'style-src' => "'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net", 'connect-src' => "'self'", 'frame-src' => 'https://www.youtube-nocookie.com', ]; return collect($communes + $directives) ->map(fn (string $valeur, string $directive) => "{$directive} {$valeur}") ->implode('; '); } private function estApplication(Request $request): bool { $route = $request->route(); if ($route === null) { return false; } if (in_array($route->getName(), ['login', 'register'], true)) { return true; } return collect($route->gatherMiddleware()) ->contains(fn ($middleware) => is_string($middleware) && str_starts_with($middleware, 'auth:')); } }