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.

High severity Application Security Updated 2026-03-01

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. 1

    Add @csrf to all forms

    {{ trim($paragraph)); ?>
    {{ trim($paragraph)); ?>

    The @csrf directive generates a hidden input with the CSRF token:

    {{ trim($paragraph)); ?>
  2. 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. 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. 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.

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