How to Fix Missing Security Headers in Laravel
Detects missing headers (CSP, HSTS, X-Frame-Options).
infrastructure security
Easy fix
10 minutes
What This Check Detects
Detects missing headers (CSP, HSTS, X-Frame-Options).
Full Documentation
What are Security Headers?
HTTP security headers are directives that tell browsers how to behave when handling your site's content. They provide crucial protection against various attacks including XSS, clickjacking, and MIME sniffing.
Security Impact
Severity: High
- Cross-Site Scripting (XSS) attacks
- Clickjacking vulnerabilities
- MIME sniffing attacks
- Man-in-the-middle attacks
Required Security Headers
1. Content Security Policy (CSP)
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline';
2. HTTP Strict Transport Security (HSTS)
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
3. X-Frame-Options
X-Frame-Options: SAMEORIGIN
4. X-Content-Type-Options
X-Content-Type-Options: nosniff
5. Referrer Policy
Referrer-Policy: strict-origin-when-cross-origin
6. Permissions Policy
Permissions-Policy: geolocation=(), microphone=(), camera=()
How to Fix
Method 1: Using Middleware
Create a custom middleware:
php artisan make:middleware SecurityHeaders
// app/Http/Middleware/SecurityHeaders.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class SecurityHeaders
{
public function handle(Request $request, Closure $next)
{
$response = $next($request);
$response->headers->set('X-Frame-Options', 'SAMEORIGIN');
$response->headers->set('X-Content-Type-Options', 'nosniff');
$response->headers->set('X-XSS-Protection', '1; mode=block');
$response->headers->set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
$response->headers->set('Referrer-Policy', 'strict-origin-when-cross-origin');
$response->headers->set('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
// CSP Header
$response->headers->set('Content-Security-Policy',
"default-src 'self'; " .
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net; " .
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " .
"font-src 'self' https://fonts.gstatic.com; " .
"img-src 'self' data: https:; " .
"connect-src 'self';"
);
return $response;
}
}
Register the middleware:
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
// ... other middleware
\App\Http\Middleware\SecurityHeaders::class,
],
];
Method 2: Using .htaccess (Apache)
# .htaccess
<IfModule mod_headers.c>
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set X-XSS-Protection "1; mode=block"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Header always set Content-Security-Policy "default-src 'self'"
</IfModule>
Method 3: Using Nginx
# nginx configuration
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
add_header Content-Security-Policy "default-src 'self'" always;
Verification Steps
- Open your website in Chrome DevTools
- Go to Network tab
- Click on your page request
- Check the Response Headers section
- Verify all security headers are present
Or use online tools:
CSP Configuration Tips
Start with a restrictive policy and gradually relax it:
// Development CSP
"default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval';"
// Production CSP (more restrictive)
"default-src 'self'; script-src 'self'; style-src 'self';"
Report CSP violations:
"report-uri /csp-report-endpoint;"
Common Pitfalls
- Don't use
'unsafe-inline'and'unsafe-eval'in production CSP if possible - Test HSTS carefully before setting long
max-agevalues - Ensure CSP allows all legitimate resources (CDNs, fonts, etc.)
Related Issues
- SSL/TLS Security
- CORS Misconfiguration
- Laravel Debug Mode
How to Fix This Issue
Your Laravel app is missing critical security headers like CSP, HSTS, and X-Frame-Options. Learn how to add them with middleware.
Read the full fix guideRelated Security Checks
Check Your Laravel App for This Vulnerability
StackShield runs this check and 30+ others automatically. No code installation required.
Start Free Trial