| name | xpath-injection-anti-pattern |
| description | Security anti-pattern for XPath injection vulnerabilities (CWE-643). Use when generating or reviewing code that queries XML documents, constructs XPath expressions, or handles user input in XML operations. Detects unescaped quotes and special characters in XPath queries. |
XPath Injection Anti-Pattern
Severity: High
Summary
XPath Injection occurs when applications insecurely embed user input into XPath queries without proper escaping or parameterization. XPath is used to navigate and query XML documents. Similar to SQL Injection, attackers can inject special characters into the input, manipulating the XPath query's logic. This can lead to authentication bypass, unauthorized access to sensitive XML data, or information disclosure about the XML document structure.
The Anti-Pattern
The anti-pattern is constructing XPath queries by concatenating user-controlled input directly into the XPath string without proper escaping or parameterization.
BAD Code Example
from lxml import etree
xml_doc = etree.fromstring('''
<users>
<user>
<name>admin</name>
<password>adminpass</password>
<role>administrator</role>
</user>
<user>
<name>guest</name>
<password>guestpass</password>
<role>user</role>
</user>
</users>
''')
def authenticate_user(username, password):
xpath_query = f"//user[name='{username}' and password='{password}']"
found_users = xml_doc.xpath(xpath_query)
return len(found_users) > 0
GOOD Code Example
from lxml import etree
xml_doc = etree.fromstring('''
<users>
<user>
<name>admin</name>
<password>adminpass</password>
<role>administrator</role>
</user>
<user>
<name>guest</name>
<password>guestpass</password>
<role>user</role>
</user>
</users>
''')
def authenticate_user_secure(username, password):
xpath_query = "//user[name=$username and password=$password]"
variables = {'username': username, 'password': password}
found_users = xml_doc.xpath(xpath_query, **variables)
return len(found_users) > 0
Detection
- Review XPath query construction: Look for any code that constructs XPath queries using string concatenation, interpolation (e.g., f-strings), or formatting methods with user-supplied input.
- Identify XPath evaluation functions: Search for calls to functions like
xpath(), evaluate(), selectNodes(), or similar methods in your XML processing library.
- Check for escaping: Verify that any user input inserted into an XPath query is properly escaped. The rules for escaping in XPath can be complex, especially for strings containing both single and double quotes.
- Test with injection payloads: Input XPath metacharacters (e.g.,
', ", and, or, comment()) to see if they alter the query's behavior or cause unexpected results.
Prevention
def escape_xpath_string(s):
if "'" in s and '"' in s:
return "concat('" + s.replace("'", "',\"'\",'") + "')"
elif "'" in s:
return '"' + s + '"'
else:
return "'" + s + "'"
Related Security Patterns & Anti-Patterns
References