Protection CSRF

  • 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.

Laisser un commentaire