Saltar a contenido

Index

Inyección XPath

Descripción

La inyección XPath es un tipo de ataque que puede alterar la intención de una consulta XPath que se ejecuta en el backend de una aplicación. Una aplicación puede ser vulnerable a este ataque si se inyectan caracteres especiales en un valor de entrada proporcionado por el usuario, dicha entrada no se filtra y se concatena con otras cadenas para construir una consulta XPath que se ejecuta contra un documento XML.

Los impactos de este ataque pueden incluir la evasión de la lógica de autenticación o la divulgación de datos sensibles dentro del documento XML consultado.

Ejemplos

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";
?>

Recomendación

Para mitigar las vulnerabilidades de inyección XPath, es importante:

  • Utilizar consultas parametrizadas o sentencias preparadas, las cuales separan la entrada del usuario de la lógica de la consulta.
  • Validar y sanear adecuadamente la entrada del usuario antes de utilizarla en consultas 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();
        }
    }
}

Enlaces

Estándares

  • 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