Voyons comment protéger très facilement votre application Laravel contre les attaques CSRF (Cross Site Request Forgery).
Qu’est-ce qu’une attaque CSRF ?
Si vous voulez avoir un exemple clair de ce en quoi ça consiste, je vous invite à aller jeter un coup d’oeil sur Wikipedia.
Dans la pratique
Une des manières efficaces de se prémunir contre ce type d’attaque est d’accompagner chaque formulaire à protéger d’un jeton (en anglais “token”) d’identification de session. Pour ce faire, lorsqu’un visiteur se connecte sur votre site, vous enregistrez en session une chaîne de caractère aléatoire. Cette même chaîne est récupérée en session et passée au formulaire, sous la forme d’un champ de type “hidden”. Lorsque le formulaire est posté, votre système de validation doit vérifier que le champ caché contient la même valeur que celle enregistrée en session. Si ça n’est pas le cas, ça signifie que quelqu’un a essayé de soumettre le formulaire depuis un autre endroit que votre site. Il faut alors annuler le traitement de ce formulaire.
Le filtre Laravel
Laravel permet de faire tout ceci très facilement via un filtre mis à votre disposition avec chaque installation du Framework. Voici le code de ce filtre:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// /app/filters.php /* |-------------------------------------------------------------------------- | CSRF Protection Filter |-------------------------------------------------------------------------- | | The CSRF filter is responsible for protecting your application against | cross-site request forgery attacks. If this special token in a user | session does not match the one given in this request, we'll bail. | */ Route::filter('csrf', function() { if (Session::token() != Input::get('_token')) { throw new Illuminate\Session\TokenMismatchException; } }); |
Que fait ce code?
Ce code enregistre un filtre qui vérifie que le jeton (token) de session généré automatiquement par Laravel est bien identique à la valeur de l’input posté sous l’identifiant “_token”. Si ça n’est pas le cas, une exception (TokenMismatchException) est lancée et le traitement du formulaire donc est arrêté.
Mise en place dans le formulaire
Pour ajouter automatiquement ce champ, il vous suffit d’utiliser la classe “Form” pour créer vos formulaires.
1 2 3 4 5 |
{{ Form::open(array('url' => 'foo/bar')) }} ... {{ Form::close() }} |
Ce code Blade va générer un code HTML similaire à ceci:
1 2 |
<form method="POST" action="/foo/bar" accept-charset="UTF-8"> <input name="_token" type="hidden" value="1fappeoJ3DO51WiqL4UqsjA5sdA2uff2YOBBK0He"> |
Le champ “_token” est bien généré et il ne vous reste plus qu’à traiter chaque envoi avec le filtre dont nous venons de parler.
Appliquer le filtre ‘csrf’
Ce que nous allons faire ici est simple. Pour chaque Route qui correspond à un envoi de formulaire, appliquons le filtre ‘csrf’:
1 2 3 4 5 |
// /app/routes.php // Pour chaque route correspondant à une action de type // post, put ou patch, appliquer le filtre csrf Route::when('*', 'csrf', array('post', 'put', 'patch'); |
Et voilà! Tous vos formulaires sont maintenant protégés contre les attaques CSRF.
Si vous souhaitez avoir un contrôle plus chirurgicale sur les formulaires à protéger, vous pouvez toujours le faire au cas par cas, avec le code suivant:
1 2 3 4 5 |
// app/routes.php // Lorsque l'action est le post de 'foo/baz', appliquer le filtre 'csrf' // et ensuite utiliser la méthode 'postBaz' de 'MonControlleur' Route::post('foo/baz', array('before' => 'csrf'), 'uses' => 'MonControlleur@postBaz'); |
Conclusion
Vous savez maintenant tout ce qu’il y a à savoir pour protéger votre application Laravel contre les attaques CSRF. Une fois encore, Laravel nous facilite grandement la tâche et remplit à merveille son rôle de Framework: Nous permettre de zoner un peu plus longtemps à côté de la machine à café.