Protezione da CSRF

Introduzione

Le cross-site request forgery sono un tipo di exploit dannoso in cui vengono eseguiti comandi non autorizzati a nome di un utente autenticato. Fortunatamente, Laravel rende facile proteggere la tua applicazione dagli attacchi di cross-site request forgery (CSRF).

Una Spiegazione della Vulnerabilità

Se non conosci le cross-site request forgeries, vediamo un esempio di come questa vulnerabilità può essere sfruttata. Immagina che la tua applicazione abbia una rotta /user/email che accetta una richiesta POST per cambiare l’indirizzo email dell’utente autenticato. Probabilmente, questa rotta si aspetta che il campo di input email contenga l’indirizzo email che l’utente vuole usare.

Senza la protezione CSRF, un sito web malevolo potrebbe creare un form HTML che punta alla rotta /user/email della tua applicazione e invia l’indirizzo email dell’utente malintenzionato:

<form action="https://your-application.com/user/email" method="POST">
    <input type="email" value="malicious-email@example.com">
</form>

<script>
    document.forms[0].submit();
</script>

Se il sito web malevolo invia automaticamente il form al caricamento della pagina, l’attaccante deve solo convincere un utente ignaro della tua applicazione a visitare il loro sito e il suo indirizzo email verrà cambiato nella tua applicazione.

Per prevenire questa vulnerabilità, dobbiamo controllare ogni richiesta POST, PUT, PATCH o DELETE in arrivo alla ricerca di un valore segreto di sessione a cui l’applicazione malevola non può accedere.

Prevenire le richieste CSRF

Laravel genera automaticamente un "token" CSRF per ogni sessione utente attiva gestita dall’applicazione. Questo token viene utilizzato per verificare che l’utente autenticato sia effettivamente la persona che sta effettuando le richieste all’applicazione. Poiché questo token è memorizzato nella sessione dell’utente e cambia ogni volta che la sessione viene rigenerata, un’applicazione malevola non può accedervi.

Il token CSRF della sessione corrente può essere accesso tramite la sessione della richiesta o tramite la funzione helper csrf_token:

use Illuminate\Http\Request;

Route::get('/token', function (Request $request) {
    $token = $request->session()->token();

    $token = csrf_token();

    // ...
});

Ogni volta che definisci un modulo HTML "POST", "PUT", "PATCH" o "DELETE" nella tua applicazione, dovresti includere un campo nascosto CSRF _token nel modulo affinché il middleware di protezione CSRF possa validare la richiesta. Per comodità, puoi utilizzare la direttiva Blade @csrf per generare il campo di input del token nascosto:

<form method="POST" action="/profile">
    @csrf

    <!-- Equivalente a... -->
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>

Il middleware Illuminate\Foundation\Http\Middleware\ValidateCsrfToken middleware, che è incluso per impostazione predefinita nel gruppo di middleware web, verificherà automaticamente che il token presente nei dati della richiesta corrisponda al token memorizzato nella sessione. Quando questi due token corrispondono, sappiamo che l’utente autenticato è quello che ha iniziato la richiesta.

Token CSRF e SPA

Se stai costruendo un SPA che utilizza Laravel come backend API, dovresti consultare la documentazione di Laravel Sanctum per informazioni sull’autenticazione con la tua API e per proteggerti dalle vulnerabilità CSRF.

Escludere URI dalla Protezione CSRF

A volte potresti voler escludere un insieme di URI dalla protezione CSRF. Ad esempio, se stai utilizzando Stripe per elaborare pagamenti e stai usando il loro sistema di webhook, dovrai escludere la route del webhook di Stripe dalla protezione CSRF poiché Stripe non saprà quale token CSRF inviare alle tue route.

Di solito, dovresti posizionare questo tipo di route al di fuori del gruppo di middleware web che Laravel applica a tutte le route nel file routes/web.php. Tuttavia, puoi anche escludere route specifiche fornendo i loro URI al metodo validateCsrfTokens nel file bootstrap/app.php della tua applicazione:

    ->withMiddleware(function (Middleware $middleware) {
        $middleware->validateCsrfTokens(except: [
            'stripe/*',
            'http://example.com/foo/bar',
            'http://example.com/foo/*',
        ]);
    })

Per comodità, il middleware CSRF è automaticamente disabilitato per tutte le route quando si eseguono i test.

X-CSRF-TOKEN

Oltre a verificare il token CSRF come parametro POST, il middleware Illuminate\Foundation\Http\Middleware\ValidateCsrfToken, incluso di default nel gruppo middleware web, controllerà anche l’intestazione della richiesta X-CSRF-TOKEN. Ad esempio, puoi memorizzare il token in un tag meta HTML:

<meta name="csrf-token" content="{{ csrf_token() }}">

Successivamente, puoi istruire una libreria come jQuery ad aggiungere automaticamente il token a tutte le intestazioni delle richieste. Questo fornisce una protezione CSRF semplice e comoda per le tue applicazioni AJAX che utilizzano tecnologie JavaScript legacy:

$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

X-XSRF-TOKEN

Laravel memorizza il token CSRF corrente in un cookie criptato XSRF-TOKEN che viene incluso in ogni risposta generata dal framework. Puoi usare il valore del cookie per impostare l’header della richiesta X-XSRF-TOKEN.

Questo cookie viene inviato principalmente per comodità dello sviluppatore, poiché alcuni framework e librerie JavaScript, come Angular e Axios, inseriscono automaticamente il suo valore nell’header X-XSRF-TOKEN nelle richieste dello stesso dominio.

Per impostazione predefinita, il file resources/js/bootstrap.js include la libreria HTTP Axios che invierà automaticamente l’header X-XSRF-TOKEN per te.

Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *