How to Fix Missing CSRF Protection in Laravel
Your Laravel forms are missing CSRF tokens, leaving users vulnerable to cross-site request forgery attacks. Learn how to fix this.
The Problem
Missing CSRF protection allows attackers to trick authenticated users into submitting malicious requests to your application. Without CSRF tokens, a malicious website can create a hidden form that submits a POST request to your Laravel app, performing actions like changing passwords, transferring funds, or deleting accounts on behalf of the logged-in user without their knowledge.
How to Fix
-
1
Add @csrf to all forms
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>The @csrf directive generates a hidden input with the CSRF token:
{{ trim($paragraph)); ?> -
2
Configure CSRF for AJAX requests
Add the CSRF token meta tag to your layout's <head>:
{{ trim($paragraph)); ?>Then configure your JavaScript HTTP client to send it automatically. With Axios (already configured in Laravel):
{{ trim($paragraph)); ?>With fetch:
{{ trim($paragraph)); ?> -
3
Verify the CSRF middleware is active
In Laravel 11+, CSRF protection is enabled by default. In earlier versions, check that VerifyCsrfToken is in your middleware stack in app/Http/Kernel.php:
{{ trim($paragraph)); ?>Do not add routes that modify data to the $except array in VerifyCsrfToken unless they are webhook endpoints with their own authentication.
-
4
Handle CSRF for SPA and API routes
For single-page applications using Laravel Sanctum, initialize the CSRF cookie before making requests:
{{ trim($paragraph)); ?>{{ trim($paragraph)); ?>API routes using token authentication (not session-based) do not need CSRF protection as they are not vulnerable to CSRF attacks.
How to Verify
Submit a form without the CSRF token and verify you receive a 419 Page Expired response. You can test with curl:
curl -X POST https://yourdomain.com/login -d "email=test@test.com&password=test"
This should return a 419 status code, confirming CSRF protection is active.
Prevention
Use Blade components and Livewire for forms, which handle CSRF automatically. Never remove the VerifyCsrfToken middleware from the web middleware group. Code review all form submissions to ensure @csrf is present. Use StackShield to verify CSRF protection is active on your public forms.
Frequently Asked Questions
Why do I get 419 Page Expired errors?
The 419 error means the CSRF token is missing or expired. Common causes: the form is missing @csrf, the user session expired, your session driver is misconfigured, or the token was not included in AJAX requests. Regenerate the token by refreshing the page.
Should I exclude webhook routes from CSRF protection?
Yes, webhook endpoints from third-party services (Stripe, GitHub, etc.) cannot include CSRF tokens. Add them to the $except array in VerifyCsrfToken and verify webhooks using their own signature mechanism instead, such as Stripe's webhook signature verification.
Related Guides
How to Prevent Cross-Site Scripting (XSS) in Laravel
XSS vulnerabilities allow attackers to inject malicious scripts into your Laravel pages. Learn how to prevent XSS with proper output encoding.
How to Fix Insecure Session Configuration in Laravel
Your Laravel session cookies are missing secure flags, enabling session hijacking and cross-site attacks. Fix your session config now.
How to Fix Missing Security Headers in Laravel
Your Laravel app is missing critical security headers like CSP, HSTS, and X-Frame-Options. Learn how to add them with middleware.
Detect This Automatically with StackShield
StackShield continuously monitors your Laravel application from the outside and alerts you when security issues are found. No installation required.
Start Free Trial