En-tête négligent

L'injection XML expliquée : Risques, attaques réelles et guide de défense complet

L'injection XML est la manipulation d'une entrée XML pour modifier la façon dont une application analyse ou interprète les données. Elle se produit lorsque des données contrôlées par l'utilisateur sont insérées dans un document XML sans validation appropriée, ce qui permet aux attaquants d'injecter des nœuds, des attributs, des entités ou des charges utiles qui modifient le flux de contrôle, contournent la logique ou déclenchent des comportements dangereux de l'analyseur. Dans les écosystèmes actuels, riches en API et axés sur l'intégration, l'injection XML reste une menace réelle que les équipes de sécurité ne peuvent ignorer.

Contrairement à la simple altération des entrées, l'injection XML exploite la puissance expressive du XML lui-même, ce qui a un impact sur les systèmes complexes, notamment SOAP, SAML, les appareils IoT, les intégrations d'entreprise et les systèmes financiers hérités.

Pourquoi l'injection XML est toujours d'actualité

Même si JSON domine les applications modernes, XML est profondément ancré dans les logiciels d'entreprise, les protocoles d'authentification et les intégrations dorsales. Les attaquants peuvent abuser des structures XML pour :

  • Altérer la logique d'entreprise
  • Injecter des nœuds non autorisés
  • Manipuler les requêtes XPath
  • Déclenchement d'une divulgation de fichiers de type XXE
  • Interrompre la validation du schéma
  • Provoquer un déni de service basé sur XML

La flexibilité du XML rend son utilisation abusive particulièrement puissante.

Exemple réel de CVE : CVE-2025-13526

CVE-2025-13526 démontre comment une simple mauvaise configuration de l'analyse XML peut conduire à la divulgation complète d'un fichier. Le système autorisait le téléchargement de fichiers de configuration XML, mais ne parvenait pas à désactiver la résolution d'entités externes.

Exemple de charge utile malveillante :

xml

<!DOCTYPE data [

]>

&xxe;

Le serveur a renvoyé le contenu de /etc/passwdqui montre comment l'injection de XML combinée à XXE peut exposer des fichiers critiques.

Surfaces d'attaque de l'injection XML

Les attaquants abusent :

  • Injection de nœuds
  • Injection d'attributs
  • Manipulation de requêtes XPath
  • Manipulation du schéma (XSD)
  • Charges utiles XXE
  • Extension d'entité pour DoS
  • Contournement logique dans les flux de travail basés sur XML

Chaque catégorie a un impact sur une couche différente du système.

Exemples d'attaques (même quantité conservée)

  1. Manipulation de l'injection de nœuds

xml

ProduitA

Charge utile injectée :

pgsql

true

Le XML qui en résulte est structurellement corrompu et peut accorder des privilèges non autorisés.

Injection XPath

python

query = f"//users/user[username/text()='{user}']"

Entrée malveillante :

bash

ou '1'='1

Cela expose les enregistrements d'utilisateurs non autorisés.

XXE Charge utile

xml

<!DOCTYPE foo [

]>&payload;

Manipulation des schémas

xml

<xs:element name="amount" type="xs:string"/>

Cela désactive le comportement de validation attendu.

Billion Laughs DoS

xml

<!ENTITY a "ha"><!ENTITY b "&a;&a;"><!ENTITY c "&b;&b;">

L'expansion massive surcharge l'analyseur.

Techniques défensives

Désactiver la résolution des entités

python

parser = etree.XMLParser(resolve_entities=False, no_network=True)

Utiliser des bibliothèques sûres

python

import defusedxml.ElementTree en tant que ET

Validation solide des schémas

python

schema.validate(input_xml)

Ne jamais concaténer des chaînes XML

Une approche plus sûre :

python

el = Element("user") name_tag.text = user_input

Tableau de comparaison

TypeCibleSévéritéImpact
Injection XMLManipulation des structuresMoyenne-élevéeDérivation logique
Injection XPathContrôle des requêtesHautAccès non autorisé
XXEMauvaise utilisation de l'analyseur syntaxiqueHautLecture de fichiers / SSRF
Injection de schémaContournement de la validationMoyenRisques liés à l'intégrité
Injection XML

Injection XML dans les tests de pénétration automatisés

Les plateformes modernes de test de pénétration pilotées par l'IA, telles que Penligent, effectuent des mutations de structure, du fuzzing XML, des tests de charge utile XPath et de la détection de mauvaise configuration de l'analyseur. Ces plateformes :

  • Découvrir les surfaces d'attaque basées sur XML
  • Identifier les points d'injection
  • Apprentissage automatique du comportement des schémas
  • Générer des charges utiles adaptatives
  • Valider le comportement de l'analyseur sous plusieurs configurations

Cela permet d'étendre considérablement la couverture de la détection.

Lignes de base en matière de sécurité et recommandations automatisées de corrections

Les plateformes automatisées peuvent également fournir :

  • Audits de configuration de l'analyseur
  • Détection des bibliothèques XML non sûres
  • Vérification des paramètres de résolution de l'entité
  • Application d'une validation XSD stricte
  • Blocage CI/CD des opérations XML non sécurisées

La détection est ainsi transformée en mesures correctives exploitables.

Script pour l'exemple

Règles Semgrep - Injection XML Python / XXE / Parsing non sécurisé

Créer un fichier :

semgrep-rules/python-xml-injection.yaml

yaml

`rules :

RÈGLE 1 : Utilisation non sécurisée de xml.etree - l'analyseur par défaut est vulnérable à XXE

  • id : python-unsafe-xml-etree severity : ERROR message : | xml.etree.ElementTree n'est pas sûr pour un XML non fiable. Il ne désactive PAS l'expansion des entités externes par défaut. Utilisez defusedxml à la place. metadata : cwe : "CWE-611" owasp : "A04:2021 XML External Entities" patterns :
    • pattern : | import xml.etree.ElementTree as ET langages : [python]

RÈGLE 2 : Utilisation directe de xml.dom.minidom - analyseur XML non sécurisé

  • id : python-unsafe-xml-minidom severity : ERROR message : | xml.dom.minidom ne désactive pas les DTDs ou l'expansion ENTITY. Ne l'utilisez PAS pour du XML non fiable. metadata : cwe : "CWE-611" pattern : | import xml.dom.minidom langages : [python]

RÈGLE 3 : XMLParser lxml dangereux avec resolve_entities=True

  • id : python-lxml-resolve-entities-enabled severity : ERROR message : | lxml XMLParser() with resolve_entities=True enables XXE. Définir resolve_entities=False et load_dtd=False. metadata : cwe : "CWE-611" motif : | XMLParser(resolve_entities=True, ...) langages : [python]

REGLE 4 : lxml avec load_dtd=True - dangereux

  • id : python-lxml-load-dtd severity : WARNING message : | load_dtd=True permet le traitement des DTD et peut permettre l'expansion des entités. Désactiver à moins que cela ne soit absolument nécessaire. metadata : cwe : "CWE-611" pattern : | XMLParser(load_dtd=True, ...) langages : [python]

REGLE 5 : Configuration de l'analyseur syntaxique manquante lors de l'utilisation de lxml.fromstring()

  • id : python-lxml-fromstring-no-safe-config severity : WARNING message : | Lxml.fromstring() appelé sans XMLParser renforcé. Assurer resolve_entities=False, no_network=True. metadata : cwe : "CWE-611" motifs :
    • pattern : | from lxml import etree - pattern : | etree.fromstring($XML) langages : [python]

RÈGLE 6 : Ne pas utiliser defusedxml lors de l'analyse d'un fichier XML externe

  • id : python-defusedxml-not-used severity : INFO message : | Message INFO : python-defusedxml-not-used n'utilise pas defusedxml, recommandé pour l'analyse XML sécurisée en Python. metadata : cwe : "CWE-611" pattern-either :
    • motif : | ET.parse($X) - pattern : | etree.parse($X) langages : [python]

RÈGLE 7 : xmltodict sans forcer l'analyseur syntaxique désamorcé

  • id : python-xmltodict-unsafe severity : WARNING message : | xmltodict peut invoquer un analyseur XML sous-jacent qui autorise XXE. Utiliser defusedxml à la place de l'analyseur syntaxique : | xmltodict.parse($X) langages : [python]

RÈGLE 8 : Utilisation dangereuse de eval() sur des données d'entrée dérivées de XML

  • id : python-eval-from-xml severity : CRITICAL message : | eval() sur une entrée dérivée de XML peut conduire à un RCE. Ne jamais évaluer directement les valeurs XML analysées. metadata : cwe : "CWE-95" owasp : "A03:2021 Injection" patterns :
    • motif : | $VAL = $XML.xpath(...) - motif : | eval($VAL) langages : [python]

RÈGLE 9 : Chargements pickle.non sûrs sur des données provenant de XML

  • id : python-pickle-on-xml severity : CRITIQUE message : | L'utilisation de pickle.loads() sur une entrée dérivée de XML peut conduire à une exécution de code arbitraire. Evitez d'utiliser pickle sur des données utilisateur. metadata : cwe : "CWE-502" motifs :
    • motif : | $DATA = etree.fromstring(...) - motif : | pickle.loads($DATA) langages : [python]`

Scanner SAST complet en Python

Il complète Semgrep en recherchant des modèles risqués, notamment :

  • Importations non sûres d'analyseurs XML
  • ENTITY / DOCTYPE usage
  • eval, exécuter, cornichon, maréchal, yaml.load modèles
  • Déclencheurs XXE en .xml, .xsd, .wsdl dossiers

Créer : python_sast_scanner.py

python

`#!/usr/bin/env python3″"" python_sast_scanner.py Scanner SAST léger et rapide, spécifique à Python, spécialisé dans les.. :

  • Injection XML / XXE
  • Utilisation non sûre de l'analyseur syntaxique
  • fonctions dangereuses (eval, exec, pickle.loads, yaml.load) Sûr pour CI ; n'exécute pas de code. Produit du JSON et une sortie non nulle en cas de découverte. """import os, re, json, sys PATTERNS = {# XML / XXE "xml_etree" : r "import\s+xml\.etree\.ElementTree", "xml_minidom" : r "import\s+xml\.dom\.minidom", "lxml_resolve_entities" : r "resolve_entities\s*=\sTrue", "lxml_load_dtd" : r "load_dtd\s=\s*True", "doctype_in_xml" : r"<!DOCTYPE", "entity_in_xml" : r"<!ENTITY",
Injection XML en un clic

Fonctions dangereuses

"eval_usage": r"\\beval\\s*\\(","exec_usage": r"\\bexec\\s*\\(","pickle_loads": r"pickle\\.loads\\s*\\(","marshal_loads": r"marshal\\.loads\\s*\\(","yaml_unsafe_load": r"yaml\\.load\\s*\\(",

} IGNORED = {".git", "venv", "env", "pycache", "dist", "build", "node_modules"} def scan_file(path) : findings = []try:with open(path, "r", encoding="utf-8″, errors="ignore") as f:for i, line in enumerate(f, 1):for rule, regex in PATTERNS.items():if re.search(regex, line) : findings.append({"rule" : rule, "line" : line.strip(), "lineno" : i, })except Exception:pass return findings def walk(root=".") : results={}for dp, dirs, files in os.walk(root) : dirs[ :] = [d for d in dirs if d not in IGNORED]for f in files:if f.endswith((".py",".xml",".xsd",".wsdl"))) : full = os.path.join(dp, f) hits = scan_file(full)if hits : results[full] = hitsreturn results def main() : root = sys.argv[1] if len(sys.argv)>1 else "." results = walk(root)print(json.dumps({"results" : results, "file_count" : len(results)}, indent=2))if results : sys.exit(3) sys.exit(0) if name = "main" : main()`

Ce qui est couvert - Python SAST Scope

Injection XML / XXE

✔ Analyseurs XML non sûrs ✔ lxml avec resolve_entities=True ✔ Chargement de DTD (potentiellement dangereux) ✔ Marqueurs XXE dans les fichiers XML stockés

Injection de code

eval()exec()

Désérialisation non sécurisée

pickle.loads()marshal.loads() ✔ dangereux yaml.load()

Autres schémas dangereux

✔ ENTITY / DOCTYPE en .xml, .xsd, .wsdl ✔ xmltodict sans parser renforcé

Conclusion

L'injection XML reste une catégorie de vulnérabilité pertinente et dangereuse. Son impact va du contournement de la logique d'entreprise à la divulgation de fichiers et au déni de service. Comprendre les comportements XML, sécuriser les analyseurs, valider la structure et incorporer des tests de pénétration automatisés sont des étapes essentielles pour garantir une sécurité robuste des applications.

Partager l'article :
Articles connexes