Aller au contenu

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