Prologo
Primi Passi
Architettura
Le Basi
Approfondimenti
Package
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’headerX-XSRF-TOKEN
per te.