Index
Injection XPath
Description
L'injection XPath est un type d'attaque qui peut modifier l'intention d'une requête XPath exécutée sur le backend d'une application. Une application peut être vulnérable à cette attaque si des caractères spéciaux sont injectés dans une valeur d'entrée fournie par l'utilisateur, que cette entrée n'est pas filtrée et est concaténée avec d'autres chaînes de caractères pour construire une requête XPath, laquelle est exécutée sur un document XML.
Les impacts de cette attaque peuvent inclure le contournement de la logique d'authentification ou la divulgation de données sensibles au sein du document XML interrogé.
Exemples
Java
String xmlInput = "<users>" +
"<user><username>admin</username><password>admin@123</password></user>" +
"<user><username>guest</username><password>guest@123</password></user>" +
"</users>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xmlInput)));
//Input example :
String inputUsername = "admin' or '1'='1' or '";
String inputPassword = "randomPassword";
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
String query = String.format("//user[username/text()='%s' and password/text()='%s']", inputUsername, inputPassword);
XPathExpression expr = xpath.compile(query);
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
System.out.println(nodes.getLength() > 0 ? "Authenticated" : "Authentication Failed");
JavaScript
const express = require('express');
const libxml = require('libxmljs');
const app = express();
const xmlInput = `<users>
<user><username>admin</username><password>admin@123</password></user>
<user><username>guest</username><password>guest@123</password></user>
</users>`;
app.post('/authenticate', (req, res) => {
const { username, password } = req.body;
const xmlDoc = libxml.parseXml(xmlInput);
const query = `//user[username/text()='${username}' and password/text()='${password}']`;
const nodes = xmlDoc.find(query);
res.send(nodes.length > 0 ? 'Authenticated' : 'Authentication Failed');
});
PHP
<?php
$xmlInput = "<users>" .
"<user><username>admin</username><password>admin@123</password></user>" .
"<user><username>guest</username><password>guest@123</password></user>" .
"</users>";
//Input example :
$inputUsername = "admin' or '1'='1' or '";
$inputPassword = "randomPassword";
$doc = new DOMDocument();
$doc->loadXML($xmlInput);
$xpath = new DOMXPath($doc);
$query = "//user[username/text()='$inputUsername' and password/text()='$inputPassword']";
$nodes = $xpath->query($query);
echo ($nodes->length > 0) ? "Authenticated" : "Authentication Failed";
?>
Recommandation
Pour atténuer les vulnérabilités d'injection XPath, il est important de :
- Utiliser des requêtes paramétrées ou des instructions préparées, qui séparent l'entrée utilisateur de la logique de la requête.
- Valider et assainir correctement les entrées de l'utilisateur avant de les utiliser dans des requêtes XPath.
import org.dom4j.Document;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import org.jaxen.SimpleVariableContext;
import java.io.File;
public class Main {
public static void main(String[] args) {
try {
// Assuming 'user' and 'pass' variables are already defined
String user = "username";
String pass = "password";
// Load your XML document
File inputFile = new File("input.xml");
SAXReader reader = new SAXReader();
Document document = reader.read(inputFile);
// Create a SimpleVariableContext and set variables
SimpleVariableContext svc = new SimpleVariableContext();
svc.setVariableValue("user", user);
svc.setVariableValue("pass", pass);
// Define your XPath expression
String xpathString = "/users/user[@name=$user and @pass=$pass]";
// Create XPath object and set the variable context
XPath safeXPath = document.createXPath(xpathString);
safeXPath.setVariableContext(svc);
// Evaluate XPath expression and check if any node is selected
boolean isExist = safeXPath.selectSingleNode(document) != null;
System.out.println(isExist);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Liens
Normes
- GDPR:
- ART_32
- PCI_STANDARDS:
- REQ_6_4
- REQ_6_5
- SOC2_CONTROLS:
- CC_2_1
- CC_3_4
- CC_4_1
- CC_7_1
- CC_7_2
- CC_7_4
- CC_7_5
- HIPAA_CONTROLS:
- SECURITY212
- SECURITY213
- SECURITY255