Comprendre la menace : le CSRF
CSRF signifie Cross-Site Request Forgery ou falsification de requête intersite.
C’est une attaque qui vise à tromper un utilisateur authentifié pour qu’il exécute malgré lui une action sur une application web où il est connecté.
Le but du jeton CSRF est de s’assurer que le formulaire vient bien de ton site, et pas d’un autre site malveillant.
« Je ne fais confiance qu’aux formulaires que j’ai moi-même générés.”
Exemple de scénario d’attaque
- L’utilisateur est connecté à son compte bancaire en ligne (session ouverte, cookie d’authentification valide).
- Il visite ensuite un site malveillant qui contient un formulaire caché :
<form action="https://banque.fr/virement" method="POST">
<input type="hidden" name="compte" value="attacker">
<input type="hidden" name="montant" value="1000">
</form>
<script>document.forms[0].submit();</script>
Ce formulaire s’exécute automatiquement dans le navigateur.
Comme le navigateur envoie automatiquement les cookies de session de la banque, la requête est interprétée comme légitime par le serveur distant.
Résultat : le virement est exécuté à l’insu de l’utilisateur.
Principe de la protection CSRF
Pour contrer cette attaque, le serveur doit s’assurer que la requête POST provient bien du site légitime, et non d’un site tiers.
La solution classique consiste à utiliser un jeton CSRF (ou anti-CSRF token).
Fonctionnement d’un jeton CSRF
- À chaque affichage de formulaire, le serveur ajoute un jeton unique et secret dans le code HTML (souvent via un champ caché).
- Ce même jeton est enregistré côté serveur (en session).
- Lors de la soumission, le serveur compare le jeton reçu à celui enregistré.
- Si les deux ne correspondent pas → la requête est rejetée.
Ainsi, un site externe ne peut pas simuler une requête valide, car il n’a pas accès au jeton CSRF stocké côté serveur.
3. Mise en œuvre de la protection CSRF dans Laravel
Laravel intègre nativement la protection CSRF à travers un middleware appelé VerifyCsrfToken, activé pour toutes les routes définies dans routes/web.php.
Remarque :
Un middleware (ou intergiciel en français) est un filtre qui s’exécute avant ou après une requête HTTP dans Laravel.
Il agit entre le navigateur et ton contrôleur.
En d’autres termes : c’est un “gardien” qui vérifie ou modifie la requête avant qu’elle atteigne ton code.
Exemple : Navigateur → Middleware → Contrôleur → Réponse → Middleware → Navigateur
Structure du middleware
Le middleware VerifyCsrfToken est désormais défini dans le cœur de Laravel,
et il est automatiquement enregistré dans la pile de middlewares.
vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php
Ce middleware vérifie que toute requête POST, PUT, PATCH ou DELETE contient un jeton CSRF valide.
Insertion du jeton CSRF dans un formulaire Blade
Dans chaque formulaire Blade, il suffit d’ajouter la directive @csrf :
<form method="POST" action="/user">
@csrf
<input type="text" name="nom">
<button type="submit">Envoyer</button>
</form>
Laravel génère alors automatiquement :
<input type="hidden" name="_token" value="XyZ9a2...">
Vérification du jeton côté serveur
Lors de la réception, Laravel compare le jeton contenu dans _token avec celui stocké dans la session de l’utilisateur.
S’il ne correspond pas, la requête est bloquée avec une erreur :
HTTP 419 Page Expired
Routes exemptées de vérification
Si certaines routes (comme des webhooks ou APIs publiques) ne doivent pas être soumises à cette vérification, elles peuvent être exclues dans le middleware :
protected $except = [
'webhook/*',
];
4. Comparaison avec d’autres protections
| Menace | Protection Laravel | Principe |
|---|---|---|
| XSS (injection JavaScript) | Échappement automatique dans Blade | Les balises HTML sont neutralisées dans les vues |
| SQL Injection | Requêtes préparées via Eloquent/PDO | Les valeurs ne sont jamais injectées directement dans le SQL |
| CSRF | Middleware VerifyCsrfToken | Vérifie la présence d’un jeton de session unique |
Pourquoi Laravel n’ajoute pas automatiquement la protection CSRF dans tous les formulaires ?
Laravel pourrait, en théorie, ajouter ce champ caché CSRF dans tous les formulaires, mais il ne le fait pas volontairement.
Voici pourquoi :
Tous les formulaires ne nécessitent pas de protection CSRF
Certains formulaires ne modifient pas de données sur le serveur (par exemple un simple formulaire de recherche en GET).
Dans ces cas-là, ajouter un jeton CSRF n’a aucun intérêt, car il n’y a aucun risque de falsification de requête.
Laravel ne peut pas savoir quel formulaire est traité par une route sécurisée
Les formulaires peuvent pointer :
- vers des routes Laravel locales (ex.
/user) ; - vers une API externe (ex.
https://api.stripe.com/checkout) ; - ou être générés dynamiquement par JavaScript.
Laravel ne peut pas deviner s’il doit ou non insérer un jeton CSRF.
Il préfère laisser le développeur décider explicitement quand la protection est nécessaire.
Cas particuliers : formulaires API ou JavaScript
Les requêtes envoyées par des frameworks front-end (comme React, Vue, ou Axios)
utilisent souvent un autre mécanisme de sécurité : le header X-CSRF-TOKEN.
Laravel génère déjà un cookie spécial pour ces requêtes.
Forcer @csrf dans tous les formulaires risquerait donc de créer des doublons
ou des incohérences dans les applications modernes.
À retenir
- Le CSRF exploite la confiance du serveur dans le navigateur de l’utilisateur.
- Le jeton CSRF empêche les sites externes de simuler une requête authentifiée.
- Laravel protège automatiquement toutes les routes
web. - Il suffit d’ajouter
@csrfdans chaque formulaire POST. - Les APIs définies dans
routes/api.phpn’ont pas besoin de CSRF car elles utilisent généralement des tokens d’accès (Bearer / JWT).
Ce contenu est réservé aux membres du site. Si vous êtes un utilisateur existant, veuillez vous connecter. Les nouveaux utilisateurs peuvent s'inscrire ci-dessous.