Index
XPathインジェクション
説明
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クエリで使用する前に、ユーザー入力を適切に検証し、サニタイズする。
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