Laravel¶
Laravel has no first-party CSP configuration, but it does have first-party nonce support through Vite - which solves the hard half of the problem. Once you call Vite::useCspNonce(), Laravel attaches the nonce to every script and style tag it generates for you, and you only have to set the header yourself.
What Laravel gives you¶
Vite::useCspNonce()to generate a nonce for the request, andVite::cspNonce()to read it back.- Automatic
nonceattributes on all script and style tags generated by the Vite directive afteruseCspNonce()has been called. - The ability to pass in an existing nonce, if it is generated further up your stack.
- Standard middleware as the place to set the header.
Setting the header¶
Create a middleware that generates the nonce and sets the header. Your URLs come from the Setup page:
public function handle(Request $request, Closure $next): Response
{
Vite::useCspNonce();
$response = $next($request);
$response->headers->set('Content-Security-Policy-Report-Only', implode('; ', [
"default-src 'self'",
"script-src 'self' 'nonce-" . Vite::cspNonce() . "' 'report-sha256'",
'report-uri https://abc123.report-uri.com/r/d/csp/reportOnly',
'report-to default',
]));
$response->headers->set('Reporting-Endpoints', 'default="https://abc123.report-uri.com/a/d/g"');
$response->headers->set('Report-To', '{"group":"default","max_age":31536000,"endpoints":[{"url":"https://abc123.report-uri.com/a/d/g"}],"include_subdomains":true}');
return $response;
}
The Reporting-Endpoints and Report-To headers tell the browser where report-to default sends reports, including the CSP Integrity reports that 'report-sha256' turns on.
Register it in your middleware stack, and switch the header name to Content-Security-Policy and the endpoint to enforce when you are ready.
Adding a nonce¶
Vite::useCspNonce() does the work. Anything rendered through the @vite directive picks the nonce up automatically; for inline scripts you write yourself, add it by hand:
<script nonce="{{ Vite::cspNonce() }}">
// allowed by the policy
</script>
Things to watch for¶
useCspNonce()has to run before the response is rendered. Calling it after$next($request)gives you a nonce in the header that no tag on the page carries.- Full-page response caching and a nonce-based policy are incompatible. If you cache rendered HTML, either exclude those routes or move to a hash-based policy.
- Livewire pages have their own considerations for CSP - check Livewire's documentation alongside this if you are running it.
Official documentation¶
Laravel - Asset Bundling (Vite): Content Security Policy Nonce
Start Monitoring with Report URI¶
Already using us for CSP? Find your CSP reporting directives on Setup, or view your CSP reports.
New to Report URI? Create an account and grab your CSP reporting directives from the Setup page.