Last active
November 11, 2024 17:59
-
-
Save valorin/d4cb9daa190fdee90603efaa8cbc5886 to your computer and use it in GitHub Desktop.
CSP Middleware - the simple CSP middleware I use across all of my projects.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Add to your .env.example and .env files | |
CSP_ENABLED=true | |
CSP_REPORT_ONLY=true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
return [ | |
// Toggle CSP on or off | |
'enabled' => env('CSP_ENABLED', true), | |
// Toggle Report-Only based on production | |
'report_only' => env('CSP_REPORT_ONLY', true), | |
// Policy directives | |
'policy' => [ | |
// Defaults to Report URI CSP Wizard URL, which is the easiest way to add a CSP to an existing site. | |
// Check it out at: https://report-uri.com/ | |
'report-uri' => ["https://<subdomain>.report-uri.com/r/d/csp/wizard"], | |
'default-src' => ["'none'"], | |
'connect-src' => ["'none'"], | |
'font-src' => ["'none'"], | |
'frame-src' => ["'none'"], | |
'img-src' => ["'self'"], | |
'manifest-src' => ["'self'"], | |
'script-src' => ["'report-sample'", "'self'"], | |
'style-src' => ["'self'"], | |
'form-action' => ["'none'"], | |
'frame-ancestors' => ["'none'"], | |
], | |
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Http\Middleware; | |
use Closure; | |
use Illuminate\Support\Facades\Vite; | |
use Illuminate\Support\Str; | |
/** | |
* Simple Content Security Policy middleware. | |
* | |
* Provides a super simple way to add a CSP to a Laravel app. | |
* Simply add the required directives to your config/csp.php file. | |
* Hooks directly into Vite to generate a Nonce for scripts and styles. | |
* | |
* !!! Don't forget to add the CSP middleware into the 'web' middleware group !!! | |
* | |
* @author Stephen Rees-Carter <https://stephenreescarter.net/> | |
* @see https://securinglaravel.com/tag/csp/ | |
*/ | |
class CSP | |
{ | |
public function handle($request, Closure $next) | |
{ | |
$config = config('csp'); | |
$response = $next($request); | |
// Ignore if CSP is disabled | |
if (! $config['enabled']) { | |
return $response; | |
} | |
// Add a nonce to the CSP for scripts and styles through Vite | |
Vite::useCspNonce(); | |
$config['policy']['script-src'][] = "'nonce-".Vite::cspNonce()."'"; | |
$config['policy']['style-src'][] = "'nonce-".Vite::cspNonce()."'"; | |
// Add Vite server to CSP if running in hot/dev mode | |
if (Vite::isRunningHot()) { | |
$vite = Vite::asset(''); | |
$config['policy']['connect-src'][] = 'wss:'.Str::after($vite, 'https:'); | |
$config['policy']['script-src'][] = $vite; | |
$config['policy']['style-src'][] = $vite; | |
} | |
// Generate the CSP header | |
$policy = collect($config['policy']) | |
->filter() | |
->map(fn ($value, $key) => "{$key} ".collect($value)->filter()->implode(' ')) | |
->implode(' ; '); | |
// Set the CSP header | |
$response->headers->set( | |
$config['report_only'] ? 'Content-Security-Policy-Report-Only' : 'Content-Security-Policy', | |
$policy | |
); | |
return $response; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- Include the nonce with the globally shared $cspNonce variable --> | |
<script src="https://evilhacker.dev/script.js" nonce="{{ Vite::cspNonce() }}" defer></script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment