- Introduction
- Prévenir les requêtes CSRF
- Exclure les URI
- X-CSRF-Token
- X-XSRF-.Token
Introduction
Les cross-site request forgeries sont un type d’exploit malveillant par lequel des commandes non autorisées sont exécutées au nom d’un utilisateur authentifié. Heureusement, Laravel permet de protéger facilement votre application contre les attaques de cross-site request forgery (CSRF).
Une explication de la vulnérabilité
Au cas où vous ne seriez pas familier avec les cross-site request forgeries, discutons d’un exemple de la façon dont cette vulnérabilité peut être exploitée. Imaginez que votre application possède une route /user/email
qui accepte une requête POST
pour modifier l’adresse électronique de l’utilisateur authentifié. Très probablement, cette route s’attend à ce qu’un champ de saisie email
contienne l’adresse électronique que l’utilisateur souhaite commencer à utiliser.
Sans protection CSRF, un site web malveillant pourrait créer un formulaire HTML qui pointe vers la route /user/email
de votre application et soumet la propre adresse électronique de l’utilisateur malveillant :
<form action="https://your-application.com/user/email" method="POST"> <input type="email" value=""></form><script> document.forms.submit();</script>
Si le site web malveillant soumet automatiquement le formulaire lors du chargement de la page, il suffit à l’utilisateur malveillant d’attirer un utilisateur peu méfiant de votre application pour qu’il visite son site web et son adresse électronique sera modifiée dans votre application.
Pour prévenir cette vulnérabilité, nous devons inspecter chaque requête entrante POST
, PUT
, PATCH
ou DELETE
pour trouver une valeur de session secrète à laquelle l’application malveillante ne peut pas accéder.
Prévenir les requêtes CSRF
Laravel génère automatiquement un « jeton » CSRF pour chaque session utilisateur active gérée par l’application. Ce jeton est utilisé pour vérifier que l’utilisateur authentifié est la personne qui effectue réellement les demandes à l’application. Comme ce jeton est stocké dans la session de l’utilisateur et qu’il change à chaque fois que la session est régénérée, une application malveillante est incapable d’y accéder.
Le jeton CSRF de la session en cours est accessible via la session de la requête ou via la fonction d’aide csrf_token
:
use Illuminate\Http\Request;Route::get('/token', function (Request $request) { $token = $request->session()->token(); $token = csrf_token(); // ...});
A chaque fois que vous définissez un formulaire HTML dans votre application, vous devez inclure un champ CSRF _token
caché dans le formulaire afin que le middleware de protection CSRF puisse valider la requête. Pour plus de commodité, vous pouvez utiliser la directive @csrf
Blade pour générer le champ d’entrée de jeton caché :
<form method="POST" action="/profile"> @csrf <!-- Equivalent to... --> <input type="hidden" name="_token" value="{{ csrf_token() }}" /></form>
Le middleware App\Http\Middleware\VerifyCsrfToken
, qui est inclus par défaut dans le groupe de middleware web
, vérifiera automatiquement que le jeton dans l’entrée de la requête correspond au jeton stocké dans la session. Lorsque ces deux jetons correspondent, nous savons que l’utilisateur authentifié est celui qui initie la requête.
Tokens CSRF & SPAs
Si vous construisez un SPA qui utilise Laravel comme backend API, vous devez consulter la documentation Laravel Sanctum pour obtenir des informations sur l’authentification avec votre API et la protection contre les vulnérabilités CSRF.
Exclure des URI de la protection CSRF
Parfois, vous pouvez souhaiter exclure un ensemble d’URI de la protection CSRF. Par exemple, si vous utilisez Stripe pour traiter les paiements et que vous utilisez leur système de webhook, vous devrez exclure votre route de gestionnaire de webhook Stripe de la protection CSRF puisque Stripe ne saura pas quel jeton CSRF envoyer à vos routes.
Typiquement, vous devriez placer ces types de routes en dehors du groupe d’intergiciel web
que le App\Providers\RouteServiceProvider
applique à toutes les routes dans le fichier routes/web.php
. Cependant, vous pouvez également exclure les routes en ajoutant leurs URI à la propriété $except
de l’intergiciel 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}. Par commodité, le middleware CSRF est automatiquement désactivé pour toutes les routes lors de l’exécution de tests.
X-CSRF-TOKEN
En plus de vérifier le CSRF token en tant que paramètre POST, le middleware App\Http\Middleware\VerifyCsrfToken
vérifiera également l’en-tête de requête X-CSRF-TOKEN
. Vous pourriez, par exemple, stocker le jeton dans une balise HTML meta
:
<meta name="csrf-token" content="{{ csrf_token() }}">
Puis, vous pouvez demander à une bibliothèque comme jQuery d’ajouter automatiquement le jeton à tous les en-têtes de requête. Cela fournit une protection CSRF simple et pratique pour vos applications basées sur AJAX utilisant la technologie JavaScript héritée:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta').attr('content') }});
X-XSRF-TOKEN
Laravel stocke le jeton CSRF actuel dans un cookie XSRF-TOKEN
crypté qui est inclus avec chaque réponse générée par le framework. Vous pouvez utiliser la valeur du cookie pour définir l’en-tête de requête X-XSRF-TOKEN
.
Ce cookie est principalement envoyé comme une commodité pour les développeurs puisque certains frameworks et bibliothèques JavaScript, comme Angular et Axios, placent automatiquement sa valeur dans l’en-tête X-XSRF-TOKEN
sur les requêtes de même origine.