Injection XPath : manipulation de requêtes sur des données XML
XPath est un langage de requête pour naviguer dans des documents XML. Une injection XPath se produit quand une application construit une expression XPath en concaténant directement une entrée utilisateur, de la même façon qu'une injection SQL se produit dans les requêtes de base de données. L'attaquant peut modifier la logique de la requête en injectant des opérateurs et fonctions XPath.
Exemple : contournement d'authentification
Authentification XPath vulnérable
<!-- Fichier XML des utilisateurs -->
<users>
<user>
<username>admin</username>
<password>secret</password>
<role>admin</role>
</user>
</users>
// Requête XPath construite par concaténation :
const query = `//user[username='${username}' and password='${password}']`;
// Payload : username = "admin' or '1'='1" / password = "x"
// Requête résultante :
//user[username='admin' or '1'='1' and password='x']
// Équivalent à : //user[username='admin']
// Retourne le nœud admin sans vérifier le mot de passe
Extraction de données via XPath aveugle
Quand la réponse n'inclut pas directement les données XML, l'attaquant peut extraire les données caractère par caractère. En utilisant des fonctions XPath comme string-length(), substring() et contains(), l'attaquant construit des requêtes booléennes dont le résultat (vrai/faux, visible dans le comportement de l'application) lui permet d'inférer le contenu du document XML.
Prévention
La correction principale est d'utiliser des requêtes XPath paramétrées (avec des variables). Toutes les implémentations XPath modernes supportent les variables, qui séparent la structure de la requête des données, comme les requêtes préparées en SQL.
XPath paramétré (Java)
// Vulnérable
String query = "//user[username='" + username + "' and password='" + password + "']";
// Correct : utilisation de variables XPath
XPath xpath = XPathFactory.newInstance().newXPath();
SimpleVariableResolver resolver = new SimpleVariableResolver();
resolver.addVariable(new QName("username"), username);
resolver.addVariable(new QName("password"), password);
xpath.setXPathVariableResolver(resolver);
String safeQuery = "//user[username=$username and password=$password]";
NodeList result = (NodeList) xpath.evaluate(safeQuery, doc, XPathConstants.NODESET);
Si les données XML ne sont pas nécessaires (les données pourraient être dans une base de données relationnelle), envisager de migrer vers SQL avec des requêtes préparées, qui bénéficient d'un support et d'une documentation plus larges pour la prévention des injections.
Pour aller plus loin
Une question après la lecture ?
Votre application interroge des données XML avec XPath ? Envoyez un message.
Ou réservez directement un cadrage de 30 minutes
Réserver un appel →