跳转至

Index

XPath 注入 (XPath Injection)

描述

XPath 注入是一种可以改变在应用程序后端执行的 XPath 查询意图的攻击类型。如果将特殊字符注入到用户提供的输入值中,并且该输入未经充分过滤就与其他字符串拼接以构建 XPath 查询,然后针对 XML 文档执行,那么应用程序就可能容易受到此类攻击。

这种攻击的影响可能包括绕过身份验证逻辑,或泄露被查询 XML 文档中的敏感数据。

示例

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

建议

为了缓解 XPath 注入漏洞,应采取以下重要措施:

  • 使用参数化查询或预编译语句,将用户输入与查询逻辑分离。
  • 在将用户输入用于 XPath 查询之前,对其进行适当的验证和清理(Sanitization)。
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();
        }
    }
}

链接

标准

  • 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