XPath Injection
XPath Injection
Description
XPath injection is a type of attack that can change the intent of an XPath query that is executed on an application’s backend. An application might be vulnerable to this attack if special characters are injected into a user-supplied input value, that input is not filtered and is concatenated with other strings to construct an XPath query, which is executed against an XML document.
Impacts of this attack can include bypassing authentication logic, or the disclosure of sensitive data within the XML document being queried.
Examples
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";
?>
Recommendation
To mitigate XPath Injection vulnerabilities, it is important to:
- Use parameterized queries or prepared statements, which separate the user input from the query logic.
- Properly validate and sanitize user input before using it in XPath queries.
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();
}
}
}
Links
Standards
- 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