• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 22/07/2022

Protégez votre code contre les failles XXE et la désérialisation non sécurisée

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Pour sécuriser son code, il est important de respecter les bonnes pratiques de sécurité mais aussi d’utiliser des fonctions qui permettent d’ajouter des mesures de sécurité supplémentaires. Dans ce chapitre, nous allons définir ce que sont les failles XXE et découvrir comment s’en prémunir.

Découvrez les XML External Entities (XXE)

Pour comprendre ce que sont les XXE, il faut d’abord définir le langage XML. Le langage XML (Extensible Markup Language) a été créé pour stocker, partager et transporter des données entre systèmes. Il est indépendant de la plateforme et du langage. 

XML est utilisé pour transmettre des données d'une plateforme à l'autre. Beaucoup d'applications web utilisent XML pour gérer les données. Il ressemble à HTML, mais fonctionne différemment car HTML est utilisé pour présenter les données en hypertexte sur un navigateur.

Revenons au formulaire de connexion d'un utilisateur. Ici, vous vous inscrivez sur un site avec votre nom, votre adresse e-mail et votre numéro de téléphone. Une fois que vous avez appuyé sur Entrée, les informations que vous avez tapées deviennent des éléments sous forme XML.

<?xml version="1.0" encoding="ISO-8859-1"?>
<users>
<user>
<username>Batman</username>
<email>batman@superheroes.bla</email>
<phone>888-123-4567</phone>
</user>
</users>

En XML, il existe des entités internes et externes.

Une entité interne est essentiellement une référence XML à un objet interne. Le code ci-dessous représente une entité interne.

<!ENTITY superhero "Batman">
<!ENTITY origin "Gotham City">
<character>&superhero;&origin;</character>

Une entité externe est une référence XML à une source externe comme un chemin de fichier ou une URL, des images, des références de documents ou des liens de fichiers. Lorsque cette balise d'entité externe est intégrée à une page web, elle sera directement affichée depuis son emplacement externe.

Dans l’exemple ci-dessous, la première entité externe, le super-héros, est une URL référencée. La deuxième entité externe, l'origine, fait référence à un chemin de fichier sur un système de fichiers Linux. Le contenu du fichier sur ce chemin sera affiché sur la page web. Le mot clé SYSTEM inclut le fichier référencé dans le document XML.

<!ENTITY superhero SYSTEM "http://www.batman.bla">
<!ENTITY origin SYSTEM "file:///usr/batman">
<character>&superhero;&origin;</character>

Découvrez le fonctionnement d'une attaque XXE

Une attaque XXE ou injection XXE est un type d'attaque contre une application qui utilise XML. Cette attaque se produit lorsque l'entrée XML contenant une référence à une entité externe est traitée par un analyseur XML mal configuré. Cette attaque peut entraîner la divulgation de données confidentielles, un déni de service, une falsification de requête côté serveur et d'autres impacts sur le système.

Comment un pirate peut-il tirer profit d'une XXE ?

Regardons la ligne du code ci-dessous.

<!ENTITY origin SYSTEM "file:///usr/batman">

Lorsque cette entité est référencée, elle affichera le contenu du fichier  /usr/batman.

Un attaquant peut avoir délibérément choisi de placer ce chemin d'accès dans le XML pour obtenir un accès non autorisé au contenu de ce fichier. Cette attaque est une forme d’injection.

Comment fonctionne l'attaque par injection XML ? 

Pour une page de connexion normale, un développeur web créera une requête AJAX POST vers une page de connexion qui utilisera un nom XML et un mot de passe comme identifiants.

Une requête POST est créée pour aller à l'URL  webdevfightshacker.bla/login.html

Une fois sur la page de connexion, les données XML présentes dans la variable xmlHero rempliront le formulaire Nom et mot de passe.

La demande POST fournit une réponse pour indiquer le succès ou l'échec.

var xmlHero = "
<hero>
<name>Batgirl</name>
<password>ilovebatman</password>
</hero>”;
$.ajax
({
type: "POST",
url: "webdevfightshacker.bla/login.html",
data: xmlHero,
success: function(response)
{ console.log(response);
}
});

Le code ci-dessus montre une requête POST qui envoie les données XML assignées à la variable xmlHero.

La page de connexion qui reçoit cette requête POST utilise ensuite une fonction d'analyse XML pour lire le contenu et l'affecter aux variables qui correspondent au nom d'utilisateur et au mot de passe du formulaire.

Une injection XXE est utilisée pour lire le contenu d'un fichier et l'afficher sur le navigateur. Imaginons que le pirate soit intéressé par un dossier spécial appelé secretpower dans le répertoire de Batgirl.

Le pirate commence à créer une description de type de document pour une entité nommée hax   et lui donne le chemin du fichier.

<!DOCTYPE hax [<!ELEMENT hax ANY >
<!ENTITY hax SYSTEM “C:\Users\SBatgirl\Desktop\secretpower”>>

Ensuite, la variable  hax  est référencée comme une entité de caractère externe XML.

var xmlHero = "
<hero>
<name>&hax;</name>
<password>ilovebatman</password>
</hero>”;

Dans ce cas, l’attaquant sera en mesure de récupérer le mot de passe de Batgirl et d’accéder à ses données.

Protégez votre code contre les injections XXE

Il existe un moyen de désactiver les entités externes dans tous les langages. Il s'agit généralement d'une balise binaire vrai/faux.

Par exemple, dans un analyseur XML PHP, le code ressemblerait à ceci :

libxml_disable_entity_loader (true) ;

Et en Java :

factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

Il existe d'autres API d'analyse XML qui peuvent avoir des entités externes activées par défaut.

Découvrez la désérialisation non sécurisée

La désérialisation non sécurisée est une vulnérabilité qui se produit lorsque des données non fiables sont utilisées pour abuser de la logique d'une application, causer un déni de service (DoS, Deny of Service), ou même exécuter du code arbitraire. Cette vulnérabilité occupe la 8e place du classement OWASP.

Pour comprendre la désérialisation non sécurisée, il faut d’abord comprendre ce qu’est la sérialisation.

Pour cet exemple, nous allons prendre un objet, comme un nom d'utilisateur et un mot de passe, et le mettre dans la base de données. Pour pouvoir être stocké, l'objet devra être converti en flux d'octets pour être transporté à travers le réseau afin d'accéder à la base de données. C'est ce qu'on appelle la sérialisation. Lorsqu'il y a un appel pour ce même objet dans la base de données, il doit être désérialisé (conversion du flux d'octets en objet) avant son utilisation.

Ce processus de sérialisation/désérialisation des objets ne se produit pas seulement avec les bases de données. Un objet peut changer son état en un flux d'octets lorsqu'il est stocké dans un fichier, d'ordinateur à ordinateur ou en se déplaçant sur le réseau.

Ces objets peuvent être des cookies, des flux vocaux, des jetons ou des fichiers cache, par exemple.

La désérialisation non sécurisée est une vulnérabilité qui expose les données à une attaque MITM  (homme du milieu), que nous avons vue précédemment, ou à une injection de code qui peut changer l'intégrité de l'objet quand il est désérialisé.

Par exemple, un cookie avec un identifiant de session et des informations d'identification est envoyé par le navigateur au serveur web exécutant Java.

Ce cookie est sérialisé en utilisant la classe Java OutputStream avec un constructeur. À partir de là, le code malveillant peut être  injecté par un attaquant au moment de la sérialisation.

Le cookie est désérialisé à l’aide de la classe ObjectInputStream de Java, sans constructeur. Le constructeur est créé après la création de l'objet. Sans vérification ni validation des entrées pendant le processus de désérialisation.

Un attaquant peut utiliser une classe Java Serializable ou Externalizable car elles sont déjà disponibles dans la bibliothèque. Les valeurs peuvent être manipulées pour créer des fonctionnalités différentes de celles de l'objet d'origine.

Voici un exemple avec Java :

public class Hacked extends Serializable {
private String cmd;
private void readObject(ObjectInputStream hackedbinary) {
hackedbinary.defaultReadObject();
Runtime.getRuntime().exec(cmd);
}
}

 Cette classe Hacked crée une bibliothèque utilisée dans le système. La valeur de la variable de classe est appelée cmd (qui correspond à l’invite de commande).

Les méthodes  readObject() defaultReadObject()  désérialisent le binaire pour coïncider avec le processus de sérialisation au début.

Le fichier  Runtime.getRuntime().exec(cmd)  ouvre une invite de commande permettant à l’attaquant de modifier efficacement la fonctionnalité de l'objet original.

Prévenez la désérialisation non sécurisée

Dans l'exemple ci-dessus, la classe Java ObjectInputStream restreint l'utilisation arbitraire de cette bibliothèque en l'enveloppant dans la bibliothèque SerialKiller. La bibliothèque Java SerialKiller a été créée pour pallier les problèmes de désérialisation.

Pour empêcher l'accès privilégié non autorisé à l'aide de l'objet désérialisé, une mesure défensive consisterait à valider les données d'entrée et à vérifier la fonctionnalité de l'objet.

En résumé

  • Des entités XML externes peuvent être utilisées pour révéler des données sensibles, des images et des références de documents enregistrées sur un ordinateur.

  • Les entités XML externes devraient être désactivées.

  • La désérialisation non sécurisée est la capacité d'un attaquant à changer l'état du code pendant sa conversion en binaire.

  • La désérialisation non sécurisée peut être évitée en créant des contrôles sur l'état du code.

Dans le prochain chapitre, nous aborderons la sécurisation de votre environnement de développement.

Exemple de certificat de réussite
Exemple de certificat de réussite