How to get Forge hosted Laravel application Security Headers perfect
SecurityTo get your security Headers perfect, you'll need the right tools, starting with a scanner.
Use this scanner, before, and then after:
https://securityheaders.com/
Before:
Here is the `SecureHeaders.php` middleware class for a fairly vanilla Filament PHP site with some jQuery in the mix.
You'll also notice a special `preload` at the end of the first header `set` command. See https://hstspreload.org/ if you want to pursue this.
The key to making this header work was to format it nicely with line feeds so we could slowly but surely trawl our site and make the corrections required.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class SecureHeaders
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$response = $next($request);
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
$response->headers->set('Referrer-Policy', 'no-referrer-when-downgrade');
$response->headers->set('Permissions-Policy', 'autoplay=(self), camera=(), encrypted-media=(self), fullscreen=(), geolocation=(self), gyroscope=(self), magnetometer=(), microphone=(), midi=(), payment=(), sync-xhr=(self), usb=()');
$cspWithNewlines = "
default-src 'self';
script-src 'self' cdn.jsdelivr.net platform.twitter.com 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline' fonts.bunny.net cdn.jsdelivr.net fonts.googleapis.com;
img-src 'self' * data:;
font-src 'self' data: fonts.bunny.net cdn.jsdelivr.net fonts.gstatic.com;
connect-src 'self';
media-src 'self';
frame-src 'self' *.bunny.net *.jsdelivr.net platform.twitter.com github.com *.youtube.com *.vimeo.com;
object-src 'none';
base-uri 'self';
report-uri
";
$response->headers->set('Content-Security-Policy', str_replace("\n", '', $cspWithNewlines));
return $response;
}
}
lang-phpOnce you have a working config, you can add the middlewares in `/bootstrap/app.php`:
->withMiddleware(function (Middleware $middleware) {
//
$middleware->append(SecureHeaders::class);
})
lang-phpAfterwards you should have this.. which actually took me hours to get perfect.
- https://danieldusek.com/enabling-security-headers-for-your-website-with-php-and-laravel.html
- https://dcblog.dev/laravel-security-headers
A special mention also to Spatie who has https://github.com/spatie/laravel-csp. I couldn't get it working so reverted to formatted output with newlines.