CSRF is a malicious activity performed by an attacker, who performs actions on behalf of an authenticated user, detrimental to web security. Fortunately, Laravel provides the tools to prevent this type of vulnerability.
CSRF attacks hijack user sessions. They do this by tricking a user into submitting a request via hidden form tags or malicious URLs (images or links) without the user's knowledge.
This attack leads to a change in user session state, data leaks, and sometimes hackers can manipulate end-user data in an application.
The image above illustrates a scenario where web security is breached. The victim sends a request by clicking on a link (received), sending a request to a website server which will produce effects desired by the hacker, who comes into possession of the information useful for accessing and manipulating the website server.
To improve the safety web of your applications, in each user session, Laravel generates secure tokens which it uses to ensure that the authenticated user is the one requesting the application.
Because this token changes every time a user session is regenerated, an attacker cannot access it.
Whenever there is a request to change user information on server side (backend) like POST
, PUT
, PATCH
e DELETE
, you must include the directive @csrf
in the request form blade
HTML. The @csrf
it is therefore a directive Blade
used to generate a hidden token validated by the application.
The directive Blade
is the syntax used within the Laravel template engine called Blade . To create a file blade
you have to give it a name – in our case form – followed by the extension of the blade. This means that the file will have the name form.blade.php
.
The file is used blade
to render views for users on the web page. There are a couple of pre-directivesdefinite or blade shorthand syntax you can use. For example, @if
check if a condition is satisfied, @empty
check if the records are not empty, @auth
check if a user is authenticated and so on.
But let's go back to the directive @csrf
. Here's how you use it:
<form method="POST" action="{{route('pay')}}">
@csrf
</form>
Previous versions of Laravel had a different setup: they both work and do the same thing.
<form method="POST" action="{{route('pay')}}">
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>
When the CSRF token is missing from the form request being submitted or if it appears invalid, Laravel throws a “Page Expired” error message with a 419 status code.
The middleware VerifyCsrfToken
handles CSRF verification within the Laravel application. The middleware
is registered in Kernel.php
and is located in the directory app/Http/Middleware
. This means that the middleware
it is triggered for requests within the web, not related to the APIs.
protected $middlewareGroups = [
'web' => [
.
.
.
.
.
\App\Http\Middleware\VerifyCsrfToken::class,
],
];
The VerifyCsrfToken middleware extends the class Illuminate\Foundation\Http\Middleware\VerifyCsrfToken
, i.e. CSRF verification is definite within the class.
Let's dig deeper to find out how Laravel handles CSRF verification.
Inside the class, we have the function tokensMatch
.
protected function tokensMatch($request)
{
$token = $this->getTokenFromRequest($request);
return is_string($request->session()->token()) &&
is_string($token) &&
hash_equals($request->session()->token(), $token);
}
in the code determines whether the session and the input CSRF tokens match.
The function does two things:
$this->getTokenFromRequest
the token from the incoming request attached via a hidden field or the request header. The token is decrypted and then returned to the token variable.protected function getTokenFromRequest($request)
{
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
try {
$token = CookieValuePrefix::remove($this->encrypter->decrypt($header, static::serialized()));
} catch (DecryptException $e) {
$token = '';
}
}
return $token;
}
In the code it gets token from header
2. Cast both the request token and the session to a string and then use hash_equals
built in PHP to compare if both strings are equal. The result of this operation is always bool (true) or (false) .
Ercole Palmeri
An ophthalmoplasty operation using the Apple Vision Pro commercial viewer was performed at the Catania Polyclinic…
Developing fine motor skills through coloring prepares children for more complex skills like writing. To color…
The naval sector is a true global economic power, which has navigated towards a 150 billion market...
Last Monday, the Financial Times announced a deal with OpenAI. FT licenses its world-class journalism…