π What is CSRF (Cross-Site Request Forgery)?
CSRF Protection in Laravel is a type of web security vulnerability that tricks a victim into submitting a malicious request unknowingly. For example, an attacker might forge a request to change the victim’s email or password without their consent, exploiting their active session.
π‘οΈ How Laravel Handles CSRF Protection
Laravel provides automatic CSRF protection through middleware. It ensures that every POST, PUT, PATCH, or DELETE request contains a valid CSRF token.
π CSRF Workflow in Laravel:
- Laravel generates a unique token per user session.
- This token is embedded in every form (
@csrfdirective). - On form submission, the middleware verifies the token.
- If the token is missing or invalid, Laravel throws a
TokenMismatchException.
π§ How to Use CSRF Protection in Laravel
1. Middleware Setup (Default)
Laravel includes the CSRF middleware automatically in the web middleware group:
// app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\VerifyCsrfToken::class,
],
];2. Add CSRF Token in Forms
Using Blade template:
<form method="POST" action="/update-profile">
@csrf
<!-- form fields -->
<button type="submit">Update</button>
</form>This inserts a hidden input with the CSRF token:
<input type="hidden" name="_token" value="TOKEN_VALUE">3. AJAX Requests with CSRF Token
In your JavaScript (e.g., jQuery):
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});In your HTML <head>:
<meta name="csrf-token" content="{{ csrf_token() }}">4. Excluding Routes from CSRF Protection
You can disable CSRF protection for specific routes:
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'webhook/*',
];β CSRF in Web Routes
- Enabled automatically for routes defined in
routes/web.php. - Applies to requests that use sessions and cookies, like standard browser form submissions.
π« CSRF in API Routes
- NOT applied by default in
routes/api.php.
Why?
- Laravel API routes are stateless and usually authenticated using API tokens, JWT, Sanctum, or Passport, not sessions.
- CSRF protection relies on sessions, which are not typically used in APIs.
β Does Laravel generate a new CSRF token on every page load?
No, Laravel does not generate a new CSRF token on every page load.
π Here’s what happens:
- When a user’s session is created (e.g., on first visit or login), Laravel generates a CSRF token and stores it in the session.
- This token remains the same for that session.
- All your forms use the same CSRF token until the session expires, or the session is regenerated.
π‘ When does the CSRF token get regenerated?
Laravel will generate a new CSRF token in the following cases:
| Event | Token Regenerated? | Notes |
|---|---|---|
| New session started | β Yes | First visit, logout/login |
| Session expired | β Yes | Session timeout or manually destroyed |
| Session manually regenerated | β Yes | Example: Session::regenerate() |
| Page reload (normal navigation) | β No | Token stays the same |
| Refresh form with same session | β No | Same token is used |
β Advantages of CSRF Protection in Laravel
| Advantage | Description |
|---|---|
| π Enhanced Security | Prevents unauthorized actions from malicious websites |
| βοΈ Automatic Middleware | Laravel handles CSRF checks with minimal setup |
| β Easy Form Integration | Just use @csrf in Blade templates |
| π Session-Based | Token is unique per session, reducing predictability |
| π‘οΈ Protects State-Changing Requests | Ensures safe usage of POST, PUT, DELETE methods |
β Disadvantages / Limitations of CSRF Protection
| Disadvantage | Description |
|---|---|
| β οΈ False Positives | Token mismatch can happen if session expires |
| β³ Token Expiry | Tokens are tied to session, which can time out unexpectedly |
| βοΈ Extra Setup for APIs | CSRF is not ideal for stateless API requests |
| π Not Enough Alone | Doesn’t prevent all security risks (e.g., XSS must also be prevented) |
π§ Best Practices for CSRF Protection in Laravel
- Always use
@csrfin forms. - Use
csrf_token()or meta tag for AJAX and SPA. - Avoid disabling CSRF middleware unless absolutely necessary.
- Combine CSRF with XSS protection for comprehensive security.
- Use HTTPS to prevent token leakage.
π§ͺ How to Test CSRF Protection in Laravel
- Try submitting a POST request without a CSRF token using a tool like Postman.
- Laravel should respond with a 419 Page Expired or TokenMismatchException.
β When to Disable CSRF Protection
Only disable CSRF protection when:
- Handling public webhooks (e.g., Stripe, PayPal).
- Working with stateless APIs that use tokens instead of sessions.
In such cases, protect the endpoints via API tokens or OAuth.
Is CSRF protection applied to API routes in Laravel?
routes/api.php because API routes are typically stateless and use token-based authentication instead.Where is the CSRF token stored?
XSRF-TOKEN) if using Laravel with JavaScript.How long does a CSRF token last?
Can I regenerate the CSRF token manually?
What happens if I submit a form without a valid CSRF token?
How do I exclude a route from CSRF protection?
App\Http\Middleware\VerifyCsrfToken, add the route to the $except array:protected $except = [
‘/webhook/endpoint’,
];
Is CSRF token required for GET requests?
Can CSRF tokens be reused across forms?
Are CSRF tokens required in APIs with Laravel Sanctum?
/sanctum/csrf-cookie to get it.π Conclusion
CSRF protection is a crucial part of Laravelβs security system. With its easy-to-use middleware and Blade integration, Laravel makes it simple to defend your application against cross-site request forgery attacks. While powerful, it should be used in combination with other security practices like XSS prevention, session management, and HTTPS.
