Faille CSRF

De Wiki du LAMA (UMR 5127)
Aller à la navigation Aller à la recherche
Auteurs : Victor BASSET et Vincent PEILLEX

Introduction

Session

  • Stocke l’état d’un client sur un site web
  • Identification de la session avec des cookies
  • Sessions sauvegardées côté serveur
  • Un cookie est configuré pour être envoyé sur un ou plusieurs domaine
  • Possibilité de générer un nouvel id pour chaque requête (exemple : Laravel)
  • Possibilité de crypter le contenu des sessions sur le serveur de stockage (utile si on on utilise un autre serveur pour le stockage

Faille CSRF

La faille CSRF ("Cross site request forgery") qui, si l’on essaie de donner une définition en français, signifie Falsification de requête inter-sites. Elle cherche à faire exécuter des actions directement sur l’ordinateur de la victime à son insu. Cette faille est compatible avec n'importe quel site, pour peu que vous y soyez connecté. Elle demande à celui qui l'exploite de connaître les liens utilisés par la victime.

Attaque

Exemple d'attaque

L’administrateur utilise cette URL pour supprimer un utilisateur : www.forum.com/index.php?profile=toto&action=supprimer

La faille CSRF consiste à le rediriger vers cette page, et ainsi lui faire supprimer un utilisateur.

Pré-requis  : l’administrateur doit être connecté sur le site vulnérable.

Différentes méthodes d'attaque

Attaquer la victime en mettant la requête illégitime dans un mail :

Mail-16.png

Attaquer la victime en mettant lançant la requête depuis un site malveillant :

Site-7.png

Optimisation

Plusieurs optimisation et vérification peuvent améliorer l’efficacité de l'attaque.

Prendre connaissance de la vulnérabilité du site attaqué :

  • Vérifier l'absence de token dans les formulaires
  • Connaître les routes sensibles du sites

Cacher les liens malveillant et éviter d'être repéré avant l'attaque :

  • Utiliser des redirections
  • Utiliser des appels AJAX

AJAX cache totalement l’action malveillante pour un utilisateur lambda. Le CORS du site victime doit autoriser les noms de domaines étrangers.

Risque

Le risque est inhérent au site visité par la victime puisque le CSRF consiste à effectuer des opérations sur un site sans le consentement de l’utilisateur et à son insu.

Voici trois exemples d’opérations qui étaient possibles par un attaquant sur des sites ou produits connus et vulnérables :

  • opérations à l’insu de l’utilisateur sur un site bancaire (par exemple, virement d’argent vers un autre compte) ;
  • changement de la configuration du routeur WiFi de la victime (via l’interface d’administration web accessible en réseau local) ;
  • changement de la configuration d’un webmail (notamment, l’ajout de filtres pour transmettre automatiquement les courriels reçus à une autre adresse).

Le risque principal est donc l’usurpation d’identité et l’exécution d’actions malveillantes sur un site.

Exemples

Cette faille a touché plusieurs sites connus durant la première décennie des années 2000. Aujourd'hui la faille est mieux protégée mais elle est malheureusement encore présente sur la toile.

Les 4 exemples réels ci-dessous montre les possibilités qu'offre cette faille :

Netflix.png Netflix en 2006, la faille permettait :

  • l'ajout d'un DVD à la file d'attente de location de la victime
  • la modification de l'adresse de livraison sur le compte
  • la modification des informations d'identification de la victime

Ing.png L'application Web de banque en ligne d'ING Direct, la faille permettait :

  • des transferts d'argent illicites

Youtube.png YouTube en 2008, la faille permettait  :

  • de réaliser presque toutes les actions de tout utilisateur.

Mcafee.png McAfee, la faille permettait  :

  • de modifier le système de leur entreprise.

Protection

Le CSRF est une attaque contre les visiteurs d’un site et non contre le site lui-même. Les moyens de protection pour les développeurs servent donc à protéger leurs utilisateurs.

La façon la plus répandue étant l'utilisation d'un jeton (token) unique en session qui sera vérifié à chaque modification, ici un exemple en PHP :

<?php
     $token = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM));
     $_SESSION['token'] = $token;
?>

Il suffit ensuite d'ajouter le token dans chaque requête envoyée au serveur.

Ici un formulaire HTML où l'on a ajouté le token qui doit être le même que celui en session :

<form>
	<!-- Pseudo de la personne à supprimer -->
	<input type="text" name="pseudo" id="pseudo" />
	<input type="submit" value="valider" />

	<!-- Notre token de vérification, bien caché -->
	<input type="hidden" name="token" value="<?php echo $token; ?>" />
</form>

Puis côté serveur, avant chaque modification, on vérifie que le token en session et celui du formulaire sont égaux :

// On vérifie que les deux token correspondent
if ($_SESSION['token'] == $_POST['token']) {
	// Vérification terminée
	// On peut supprimer l'utilisateur
}

On peut améliorer la protection par token avec l'ajout d'un délai d'expiration de celui-ci (10 min).

Conclusion

Sources

https://openclassrooms.com/fr/courses/2091901-protegez-vous-efficacement-contre-les-failles-web/2863569-la-csrf

https://www.cert.ssi.gouv.fr/information/CERTA-2008-INF-003/

https://www.leblogduhacker.fr/sandbox/csrf.php?#.W-gXIXVKgqo

https://en.wikipedia.org/wiki/Cross-site_request_forgery#Example_and_characteristics