spatie/laravel-csp
Set Content Security Policy (CSP) headers in Laravel to control which scripts, styles, and resources can load and where they can send data. Helps prevent XSS and malicious third-party scripts. Includes report-only mode, nonces, and easy config.
composer require spatie/laravel-csp
php artisan vendor:publish --tag=csp-config
bootstrap/app.php:
->withMiddleware(function (Middleware $middleware) {
$middleware->append(Spatie\Csp\AddCspHeaders::class);
})
config/csp.php to include presets (e.g., Spatie\Csp\Presets\Basic::class).
'presets' => [
Spatie\Csp\Presets\Basic::class,
Spatie\Csp\Presets\Google::class, // Add third-party services
],
Block Inline Scripts/Styles:
Add a directive to config/csp.php to restrict inline scripts:
'directives' => [
[Directive::SCRIPT, [Keyword::SELF, Keyword::NONCE]],
],
Then use @cspNonce in Blade:
<script @cspNonce>
console.log('Safe inline script');
</script>
Middleware Integration:
AddCspHeaders middleware.Route::get('/admin', AdminController::class)
->middleware(AddCspHeaders::class . ':' . AdminPreset::class);
Blade Directives:
<head>
@cspMetaTag
</head>
<style @cspNonce>
body { color: red; }
</style>
Dynamic Policies:
Csp::addDirective() in controllers/middleware:
use Spatie\Csp\Csp;
public function __construct() {
Csp::addDirective(Directive::SCRIPT, Keyword::NONCE);
}
CSP_ENABLED_WHILE_HOT_RELOADING=true in .env).GoogleFonts, Stripe) or create custom ones.report_uri in config/csp.php to log CSP violations:
'report_uri' => env('CSP_REPORT_URI', 'https://your-report-endpoint.com'),
@cspNonce on inline scripts/styles triggers violations.@cspNonce or disable nonces (CSP_NONCE_ENABLED=false).unsafe-inline or unsafe-eval may break legacy scripts.report-only mode first:
'report_only_presets' => [Spatie\Csp\Presets\Basic::class],
report_uri logs for blocked resources. Example:
{
"csp-report": {
"document-uri": "https://example.com",
"violated-directive": "script-src",
"effective-directive": "script-src 'self'",
"original-policy": "'self'",
"disposition": "enforce",
"blocked-uri": "inline:console.log('hacked')"
}
}
Console > Security > Content Security Policy) to validate policies.Spatie\Csp\Preset to create service-specific policies:
namespace App\Csp;
use Spatie\Csp\Directive;
use Spatie\Csp\Keyword;
use Spatie\Csp\Preset;
class CustomServicePreset implements Preset {
public function getDirectives(): array {
return [
[Directive::CONNECT, ['api.custom-service.com']],
];
}
}
if (auth()->user()->isAdmin()) {
Csp::addDirective(Directive::SCRIPT, ['admin-panel.com']);
}
reporting_endpoints:
'reporting_endpoints' => [
'default' => 'https://example.com/csp-reports',
'analytics' => 'https://analytics.example.com/report',
],
How can I help you explore Laravel packages today?