Articles

Laravel Web Security: What is Cross-Site Request Forgery (CSRF) ?

In this Laravel tutorial we talk about Web Security and how to protect a web application from Cross-Site Request Forgery or CSRF attacks.

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.

What is CSRF?

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.

How to prevent CSRF requests

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 POSTPUTPATCHDELETE, 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.

Innovation newsletter
Don't miss the most important news on innovation. Sign up to receive them by email.
<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.

How and where the CSRF verification takes place

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:

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

Innovation newsletter
Don't miss the most important news on innovation. Sign up to receive them by email.

Latest Articles

Innovative intervention in Augmented Reality, with an Apple viewer at the Catania Polyclinic

An ophthalmoplasty operation using the Apple Vision Pro commercial viewer was performed at the Catania Polyclinic…

May 3, 2024

The Benefits of Coloring Pages for Children - a world of magic for all ages

Developing fine motor skills through coloring prepares children for more complex skills like writing. To color…

May 2, 2024

The Future is Here: How the Shipping Industry is Revolutionizing the Global Economy

The naval sector is a true global economic power, which has navigated towards a 150 billion market...

May 1, 2024

Publishers and OpenAI sign agreements to regulate the flow of information processed by Artificial Intelligence

Last Monday, the Financial Times announced a deal with OpenAI. FT licenses its world-class journalism…

April 30 2024