CSRF Protection
EasyVerifies CSRF token implementation on forms and APIs.
What is CSRF Protection?
Cross-Site Request Forgery (CSRF) is an attack that forces authenticated users to execute unwanted actions. Laravel provides built-in CSRF protection through tokens that verify each request originates from your application.
Security Impact
Severity: High
- Unauthorized actions performed as legitimate users
- Account takeover
- Data modification or deletion
- Privilege escalation
- Financial fraud
How to Fix
1. Ensure CSRF Middleware is Active
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
// ... other middleware
\App\Http\Middleware\VerifyCsrfToken::class,
],
];
2. Add CSRF Token to Forms
{{-- Blade template --}}
<form method="POST" action="/profile">
@csrf
<input type="text" name="name">
<button type="submit">Update</button>
</form>
3. Configure AJAX Requests
// resources/js/app.js
// Add CSRF token to all AJAX requests
document.addEventListener('DOMContentLoaded', function() {
const token = document.querySelector('meta[name="csrf-token"]').content;
// Using Fetch API
fetch('/api/endpoint', {
method: 'POST',
headers: {
'X-CSRF-TOKEN': token,
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
});
// Using Axios (auto-configured)
axios.post('/api/endpoint', data);
});
{{-- Add meta tag in layout --}}
<meta name="csrf-token" content="{{ csrf_token() }}">
4. Configure Axios (Automatic)
// resources/js/bootstrap.js
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// CSRF token automatically added
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
}
5. Exclude Routes from CSRF (Use Carefully)
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'stripe/*', // Webhook routes
'api/*', // API routes (use Sanctum instead)
];
Verification Steps
- Submit a form without
@csrf- should get 419 error - Submit with
@csrf- should succeed - Try replaying an old request - should fail
- Test AJAX requests include CSRF token
- Verify API routes use proper authentication
Best Practices
1. Use Sanctum for APIs
// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
Route::post('/user/update', [UserController::class, 'update']);
});
2. Handle CSRF Exceptions Gracefully
// app/Exceptions/Handler.php
use Symfony\Component\HttpKernel\Exception\HttpException;
public function render($request, Throwable $e)
{
if ($e instanceof \Illuminate\Session\TokenMismatchException) {
return redirect()
->back()
->withInput($request->except('password'))
->withErrors(['csrf' => 'Your session has expired. Please try again.']);
}
return parent::render($request, $e);
}
3. SPA Configuration
// routes/web.php
Route::get('/sanctum/csrf-cookie', function (Request $request) {
return response()->noContent();
});
// Before making authenticated requests
await axios.get('/sanctum/csrf-cookie');
await axios.post('/api/endpoint', data);
Related Issues
- Session Configuration
- Brute Force Protection
- API Rate Limiting
Automatically detect this issue
StackShield can automatically scan your Laravel application for this security issue and alert you when it's detected.
Start Free Trial