How to Fix CSRF Protection in Laravel

Verifies CSRF token implementation on forms and APIs.

application security Easy fix 10 minutes

What This Check Detects

Verifies CSRF token implementation on forms and APIs.

Full Documentation

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

  1. Submit a form without @csrf - should get 419 error
  2. Submit with @csrf - should succeed
  3. Try replaying an old request - should fail
  4. Test AJAX requests include CSRF token
  5. 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

How to Fix This Issue

Your Laravel forms are missing CSRF tokens, leaving users vulnerable to cross-site request forgery attacks. Learn how to fix this.

Read the full fix guide

Related Security Checks

Check Your Laravel App for This Vulnerability

StackShield runs this check and 30+ others automatically. No code installation required.

Start Free Trial