Cross-Site Request Forgery (CSRF)
What is Cross-Site Request Forgery?
CSRF (Cross-Site Request Forgery) is a web application security vulnerability that allows an attacker to trick the browser of an authenticated user into performing unwanted actions on a website where the user is already logged in. In other words, the attacker abuses the trust the application has in the user's browser session to perform actions without the user's knowledge or consent.
Impact of CSRF
The impact of a CSRF attack depends on which actions the attacker can trigger on behalf of the user. Potential impacts include:
- Account data changes: changing the user's password, email address, or other personal data.
- Unauthorized transactions: making purchases, transferring money, or triggering other financial operations.
- Posting unwanted content: publishing comments, messages, or any other content as the user.
- Application setting changes: modifying privacy or security settings.
- Access to sensitive data: in some scenarios, weak authorization can turn CSRF into broader data exposure.
How does a CSRF attack happen?
A CSRF attack usually happens like this:
- The user logs in to a legitimate web application.
- The user visits a malicious website or clicks a malicious link. The page/link contains hidden code that sends a request to the legitimate application.
- The user's browser (with an active session) sends the request along with cookies/session data.
- The legitimate application processes the request as if it were initiated by the authenticated user.
- The attacker causes an unwanted action in the application under the user's session.
Mitigation for Cross-Site Request Forgery (CSRF)
Laravel provides built-in mechanisms to protect applications against CSRF attacks.
VerifyCsrfToken middleware
Laravel includes the VerifyCsrfToken middleware by default. It automatically checks for a valid CSRF token on POST, PUT, PATCH, and DELETE requests. Tokens are generated automatically and included in forms (Laravel CSRF Protection).
Blade @csrf directive
In Blade views, use @csrf within forms to generate the hidden input with the CSRF token (Preventing CSRF requests).
# login.blade.php <form method="POST"> {{-- Enable CSRF protection in the form --}} @csrf {{-- Form fields --}}</form>
Manual CSRF token validation
If you need to validate the CSRF token manually (for example, for certain AJAX workflows), you can use $request->validate():
# routes/web.php use Illuminate\Http\Request;use Illuminate\Support\Facades\Route; Route::post('/profile', function (Request $request) { $request->validate([ '_token' => 'required', ]);});
Excluding routes from CSRF protection
In some cases, you may want to exclude certain routes from CSRF protection (for example, webhooks). You can register route patterns to exclude in the middleware configuration:
# bootstrap/app.php use Illuminate\Foundation\Application;use Illuminate\Foundation\Configuration\Exceptions;use Illuminate\Foundation\Configuration\Middleware; return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware) { $middleware->validateCsrfTokens(except: [ 'stripe/*', 'http://example.com/foo/bar', 'http://example.com/foo/*', ]); }) ->withExceptions(function (Exceptions $exceptions) { // })->create();
Additional CSRF security recommendations:
- Ensure
VerifyCsrfTokenis enabled for web requests. - Do not disable CSRF protection unless strictly necessary and you understand the security trade-offs.
- Use CSRF tokens on all state-changing requests.
- Consider SameSite cookies for additional protection.