Les attaques CSRF sont souvent utilisées pour compromettre les données et fonctionnalités d’une application web.
Principes, impacts, exploitations possibles, nous vous présentons dans cet article une vue d’ensemble de la vulnérabilité CSRF ainsi que les bonnes pratiques et mesures à implémenter pour prévenir les risques d’attaques.
Qu’est-ce qu’une vulnérabilité CSRF ?
Une vulnérabilité CSRF (pour Cross-Site Request Forgery, en français : falsification de requête inter-site) est une faille qui permet à un attaquant d’abuser à la fois d’un utilisateur, d’un navigateur web et d’un serveur. Le principe est assez simple. L’objectif de l’attaque est de forcer un utilisateur authentifié sur un site ou une application web à exécuter des actions spécifiques à son insu.
Pour ce faire, il s’agit de corrompre la relation entre un navigateur web et un serveur, conçue en théorie, pour empêcher différents sites et applications web d’interférer les uns avec les autres. Lors d’une attaque réussie, une faille CSRF peut permettre à un attaquant de forcer le changement d’un mot de passe et/ou autres informations personnelles et ainsi récupérer des données sensibles si la victime est un utilisateur avec des droits standards. Si la victime détient un compte administrateur, une attaque CSRF peut compromettre l’ensemble de l’application web.
De manière générale, lorsqu’une fonctionnalité est vulnérable aux attaques CSRF, les attaquants cherchent à pousser les utilisateurs à charger une page malveillante.
Cette page contenant du code malveillant enverra des requêtes via le navigateur d’un utilisateur comme s’il s’agissait d’une action légitime de ce dernier, ce qui permet à l’attaquant de réaliser des actions telles que la modification du mot de passe et/ou d’autres informations personnelles ou le changement des configurations et des paramètres personnels de l’utilisateur sur la plateforme vulnérable.
L’impact d’une attaque CSRF réussie peut donc être assez sévère. Les attaquants s’appuient souvent sur des techniques d’ingénierie sociale (via du phishing généralement avec l’envoi d’un lien par email par exemple dont l’objectif est de rediriger un utilisateur vers un site malveillant) pour en augmenter les chances de succès.
Enfin, une dernière précision : les attaques CSRF visent généralement les demandes de modification (mot de passe et autres) et non le vol de données, car les attaquants n’ont aucun moyen de voir la réponse à la demande falsifiée.
Quelles sont les conditions nécessaires à une attaque CSRF ?
Pour mener à bien une attaque CSRF, certaines conditions doivent être remplies :
- L’ authentification doit être basée uniquement sur les cookies. Le déclenchement de l’attaque implique une ou plusieurs requêtes HTTP et l’application s’appuie seulement sur les cookies pour permettre l’authentification de l’utilisateur.
- Tous les paramètres de requête doivent être prévisibles. Les requêtes contiennent des paramètres dont l’attaquant peut déterminer ou deviner les valeurs.
- L’application cible doit contenir une fonctionnalité intéressante et/ou critique pour un attaquant. Plusieurs cas possibles : des fonctionnalités liées à des niveaux de droits élevés, des actions qui modifieront des données spécifiées par l’utilisateur, etc.
Comment se protéger contre les attaques CSRF ?
Les attaques CSRF sont relativement simples à contrer. Pour ce faire, deux mesures de sécurité peuvent être mises en œuvre : implémenter des jetons CSRF ou utiliser l’attribut SameSite sur les cookies.
Implémenter des jetons CSRF pour prévenir les attaques
Pour se protéger contre les attaques CSRF, une mesure de sécurité courante consiste en l’implémentation de jetons CSRF.
Les jetons CSRF sont des valeurs uniques générées aléatoirement côté serveur et envoyées au client. Ces valeurs étant uniques pour chaque requête, elles permettent de renforcer la sécurité d’une application en rendant difficile (voire impossible) pour un attaquant de les deviner et donc d’exploiter une vulnérabilité CSRF.
Par ailleurs, certains frameworks, tels que Django (Python) et Laravel (PHP), intègrent des middlewares activés par défaut assurant une protection contre les attaques CSRF.
Utiliser l’attribut SameSite sur les cookies pour contrer les attaques CSRF
SameSite est un attribut qu’une application peut insérer sur les cookies. En effet, lorsque cet attribut est placé sur les cookies de sessions, ceux-ci ne seront pas envoyés au serveur si la requête ne provient pas du domaine de l’application.
L’application recevant la requête ne sera pas capable de relier la requête à un quelconque utilisateur et par conséquent ne la traitera pas. Cela permet donc en théorie de se protéger totalement contre les attaques CSRF.
En revanche, l’attribut SameSite ne prend pas en compte les sous-domaines. Ainsi, un utilisateur ayant le contrôle d’un sous domaine, pourra compromettre l’application via une attaque CSRF. Par exemple, il serait possible d’attaquer la plateforme « vaadata.com » à partir du sous domaine « evil.vaadata.com ».
Pour éviter cette faille de sécurité, une liste des suffixes publics a été créée pour que les navigateurs modifient leur comportement de validation SameSite.
Regardons de plus près le fonctionnement de l’attribut SameSite :
L’application demande au navigateur de l’utilisateur de créer des cookies via un en-tête Set-Cookie. Par exemple, si nous avons affaire à une application PHP/Laravel, il est très probable que nous ayons une valeur d’en-tête similaire à celle-ci :
Set-Cookie: PHPSESSID=VxTGA2T1T0kE
L’en-tête Set-Cookie autorise plusieurs indicateurs afin d’améliorer la sécurité des cookies de l’utilisateur : SameSite, Expires, Domain, etc.
SameSite peut être utilisé avec différentes valeurs : Strict et Lax. Lorsque l’attribut SameSite est défini sur « Strict » (SameSite=Strict), cela signifie que le navigateur de l’utilisateur n’enverra jamais de cookies avec les requêtes inter-sites. Le cookie n’est transmis que pour les demandes provenant du même domaine et sous-domaines.
Set-Cookie: PHPSESSID=VxTGA2T1T0kE; Max-Age=43200; Secure; HttpOnly; SameSite=Strict
Si l’attribut « Lax » est défini (SameSite=Lax), le navigateur du client recevra l’instruction d’envoyer des cookies uniquement sur les requêtes GET qui peuvent provoquer une navigation entre domaines de premier niveau. Cette configuration garantit que les clients auront toujours accès aux ressources de votre site web si l’interaction inter-site est voulue.
Set-Cookie: PHPSESSID=VxTGA2T1T0kE; Max-Age=43200; Secure; HttpOnly; SameSite=Lax
La définition explicite des attributs pour les cookies SameSite améliore la sécurité contre les attaques CSRF, dès lors qu’elle empêche le navigateur d’envoyer des requêtes intersites incluant des cookies de session. Pour plus d’informations sur le principe et l’implémentation de l’attribut Samesite, vous pouvez consulter notre article dédié : Se protéger des attaques CSRF avec l’instruction SameSite sur les cookies.
Comment les navigateurs modernes contrent les attaques CSRF ?
Les premières attaques CSRF ont été observées dès 2000. À l’époque, les mesures de protection étaient encore rudimentaires. Depuis, la donne a changé.
Les principaux navigateurs tels que Mozilla Firefox et Google Chrome ont implémenté des mesures anti-CSRF début 2020. En effet, ils fixent l’attribut par défaut des cookies pour « SameSite=Lax » chaque fois qu’il n’est pas défini par une application ou un site web. Cette mesure a considérablement réduit le nombre d’attaques de type CSRF. Par ailleurs, c’est l’une des raisons pour lesquelles les failles CSRF ne figurent plus dans le Top Ten de l’OWASP.
Concernant le navigateur Chrome, il est intéressant de noter qu’il n’autorise les requêtes POST sur SameSite=Lax que si le cookie a été défini il y a moins de 120 secondes. Chrome prévoit de supprimer cette intervention (« Lax+POST ») à l’avenir.
En d’autres termes, Chrome fera une exception pour les cookies définis sans attribut SameSite il y a moins de 2 minutes. Ces cookies seront également envoyés avec des requêtes inter-sites non autonomes (par exemple, POST), alors que les cookies SameSite=Lax normaux exigent que les requêtes inter-sites utilisent une méthode HTTP sûre (par exemple, GET). Cela peut potentiellement ouvrir une petite brèche pour les attaques CSRF, même si elles dépendront un peu plus de l’ingénierie sociale.
En résumé, les CSRF sont un type d’attaque sur les applications web et sa principale caractéristique est d’inciter un utilisateur authentifié à effectuer une action non souhaitée. Une attaque CSRF réussie dépend d’un mécanisme d’authentification faible qui repose uniquement sur les cookies pour gérer les sessions des utilisateurs. Allant vers l’intégration de la sécurité par défaut, les navigateurs modernes appliquent désormais des politiques plus strictes en matière de cookies, tandis que certains frameworks tels que Django (Python) et Laravel (PHP) embarquent des mécanismes anti-CSRF. Deux protections principales peuvent être mises en place contre la vulnérabilité CSRF. La première repose sur les attributs des cookies, et la seconde sur l’implémentation, dans l’application web, de token anti-CSRF, qui sont non prédictibles et gérés uniquement côté serveur. Pour une sécurité renforcée, nous vous recommandons d’appliquer les deux techniques.