Protezione CSRF

  • Introduzione
  • Prevenire le richieste CSRF
    • Escludere gli URI
  • X-CSRF-Token
  • X-XSRF-Token

Introduzione

Le falsificazioni di richieste cross-site sono un tipo di exploit malevolo per cui vengono eseguiti comandi non autorizzati per conto di un utente autenticato. Fortunatamente, Laravel rende facile proteggere la tua applicazione dagli attacchi cross-site request forgery (CSRF).

Una spiegazione della vulnerabilità

Nel caso tu non abbia familiarità con le cross-site request forgeries, discutiamo un esempio di come questa vulnerabilità può essere sfruttata. Immaginate che la vostra applicazione abbia una rotta /user/email che accetta una richiesta POST per cambiare l’indirizzo email dell’utente autenticato. Molto probabilmente, questa rotta si aspetta un campo di input email che contenga l’indirizzo email che l’utente vorrebbe iniziare ad usare.

Senza protezione CSRF, un sito web maligno potrebbe creare un modulo HTML che punta alla rotta /user/email della vostra applicazione e invia l’indirizzo email dell’utente maligno:

<form action="https://your-application.com/user/email" method="POST"> <input type="email" value=""></form><script> document.forms.submit();</script>

Se il sito web maligno invia automaticamente il modulo quando la pagina viene caricata, l’utente maligno deve solo attirare un ignaro utente della vostra applicazione a visitare il suo sito web e il suo indirizzo email verrà cambiato nella vostra applicazione.

Per prevenire questa vulnerabilità, abbiamo bisogno di ispezionare ogni richiesta POST, PUT, PATCH, o DELETE in entrata per un valore di sessione segreto 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 è usato per verificare che l’utente autenticato sia la persona che effettivamente effettua 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 è in grado di accedervi.

Al token CSRF della sessione corrente si può accedere 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 si definisce un modulo HTML nella propria applicazione, si dovrebbe includere un campo nascosto CSRF _token nel modulo in modo che il middleware di protezione CSRF possa validare la richiesta. Per comodità, si può usare la direttiva @csrf Blade per generare il campo di input nascosto del token:

<form method="POST" action="/profile"> @csrf <!-- Equivalent to... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /></form>

Il middleware App\Http\Middleware\VerifyCsrfToken, che è incluso di default nel gruppo di middleware web, verificherà automaticamente che il token nell’input 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 & SPA

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

Escludere gli URI dalla protezione CSRF

A volte potresti voler escludere un insieme di URI dalla protezione CSRF. Per esempio, se si usa Stripe per elaborare i pagamenti e si utilizza il loro sistema webhook, è necessario escludere la propria rotta Stripe webhook handler dalla protezione CSRF, poiché Stripe non saprà quale token CSRF inviare alle proprie rotte.

In genere, si dovrebbe mettere questo tipo di rotte fuori dal gruppo web middleware che il App\Providers\RouteServiceProvider applica a tutte le rotte nel file routes/web.php. Tuttavia, si possono anche escludere le rotte aggiungendo i loro URI alla proprietà $except del middleware VerifyCsrfToken:

<?phpnamespace App\Http\Middleware;use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;class VerifyCsrfToken extends Middleware{ /** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = ;}

{tip} Per comodità, il middleware CSRF è automaticamente disabilitato per tutte le rotte quando si eseguono i test.

X-CSRF-TOKEN

Oltre a controllare il token CSRF come parametro POST, il middleware App\Http\Middleware\VerifyCsrfToken controllerà anche l’header della richiesta X-CSRF-TOKEN. Si potrebbe, per esempio, memorizzare il token in un tag HTML meta:

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

Poi, si può istruire una libreria come jQuery per aggiungere automaticamente il token a tutte le intestazioni di richiesta. Questo fornisce una protezione CSRF semplice e conveniente per le vostre applicazioni basate su AJAX che utilizzano la tecnologia legacy JavaScript:

$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta').attr('content') }});

X-XSRF-TOKEN

Laravel memorizza il token CSRF corrente in un cookie XSRF-TOKEN criptato che è incluso in ogni risposta generata dal framework. È possibile utilizzare il valore del cookie per impostare l’intestazione della richiesta X-XSRF-TOKEN.

Questo cookie viene inviato principalmente come comodità per gli sviluppatori, poiché alcuni framework e librerie JavaScript, come Angular e Axios, inseriscono automaticamente il suo valore nell’intestazione X-XSRF-TOKEN sulle richieste same-origin.

Lascia un commento