routeIs('bo*') ? "'unsafe-eval'" : ''; $jsdelivrUrl = 'https://cdn.jsdelivr.net'; $openStreetMapTiles = 'https://*.tile.openstreetmap.org'; $this->declareNonce($nonce); $this->removeUnwantedHeaders($this->unwantedHeaderList); $response = $next($request); $response->headers->set('Referrer-Policy', 'no-referrer-when-downgrade'); $response->headers->set('X-Content-Type-Options', 'nosniff'); $response->headers->set('X-XSS-Protection', '1; mode=block'); $response->headers->set('X-Frame-Options', 'SAMEORIGIN'); $response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload'); // * Ignore CSP on some conditions. if ( $appDebug && ( $response->isClientError() || // Ignition $response->isServerError() || // Ignition Vite::isRunningHot() || // Vite ($telescopeEnabled && str_starts_with($request->path(), 'telescope')) // Telescope ) ) { return $response; } $cspPolicies = [ "default-src 'none';", "base-uri 'self';", "manifest-src 'self';", "media-src 'self' blob: {$appUrl};", // * CKEDITOR Specific https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/csp.html "connect-src 'self' blob: " . implode(' ', [ 'https://yl.s-web.fr/', // * BAN address autocomplete (api-adresse.data.gouv.fr) 'https://api-adresse.data.gouv.fr', 'https://maps.googleapis.com', // * Google reCAPTCHA 'https://www.google.com/recaptcha/', 'https://recaptcha.google.com/recaptcha/', 'https://www.google.com', 'https://www.recaptcha.net/', // * VITE DEV $viteDevSocket, $viteDevOrigin, ]) . ';', "img-src 'self' data: blob: " . implode(' ', [ 'https://maps.googleapis.com', 'https://maps.gstatic.com', $viteDevOrigin, $openStreetMapTiles, ]) . ' data:;', 'child-src ' . implode(' ', []) . ';', "frame-src 'self' " . implode(' ', [ 'https://www.google.com/recaptcha/', 'https://recaptcha.google.com/recaptcha/', 'https://www.google.com/maps/', 'https://www.youtube.com/embed/', 'https://player.vimeo.com/', 'https://e.issuu.com/embed.html?', ]) . ';', "object-src 'none';", "font-src 'self' data: " . \implode(' ', [ 'https://fonts.gstatic.com', // * VITE DEV $viteDevOrigin, ]) . ';', // ! Using CKEditor will must have unsafe-inline style "style-src 'self' 'unsafe-inline' " . \implode(' ', [ $jsdelivrUrl, 'https://cdnjs.cloudflare.com', 'https://fonts.googleapis.com', 'https://use.fontawesome.com', // * File Manager // * VITE DEV $viteDevOrigin, ]) . ';', // ! If you dont use ckeditor use this // "style-src 'self' 'nonce-$nonce';", "script-src 'self' 'nonce-$nonce' 'strict-dynamic' " . \implode(' ', [ 'https: blob:', $jsBo, 'https://www.googletagmanager.com', 'https://cdnjs.cloudflare.com', 'https://www.google-analytics.com', // * VITE DEV $viteDevOrigin, ]) . ';', ]; $response->headers->set( 'Content-Security-Policy', implode(' ', $cspPolicies) ); $response->headers->set('Feature-Policy', 'fullscreen \'self\'; geolocation \'self\';'); return $response; } /** * Remove unwanted headers * * @param string[] $headerList List of headers to remove from the response * @return void */ private function removeUnwantedHeaders(array $headerList) { foreach ($headerList as $header) { header_remove($header); } } private function declareNonce(?string $value): void { Vite::useCspNonce($value); $this->container->singleton('csp_nonce', $value); } }