Xpath Injection in Django with Bearer Tokens
Xpath Injection in Django with Bearer Tokens — how this specific combination creates or exposes the vulnerability
XPath Injection occurs when an attacker can influence an XPath expression constructed from uncontrolled input. In Django, this risk can arise when you use third-party libraries or custom integrations that build XPath expressions dynamically, for example while querying XML or HTML documents (e.g., via lxml or similar parsers). If user-controlled data is concatenated into the XPath string without proper escaping or parameterization, an attacker can alter the logic of the query.
Bearer tokens are commonly used for HTTP API authentication in Django-based services. When an API endpoint accepts a bearer token from request headers and uses it in server-side processing — such as validating the token against an XML-based identity provider configuration or an internal policy document represented as XML — the token value may be incorporated into XPath expressions. If the token or data derived from it is reflected into XPath without sanitization, this creates an injection vector. For example, an attacker could supply a token like ' or //user/password/text() = 'x and, depending on how the expression is assembled, potentially extract sensitive configuration data or bypass authorization checks.
Consider a scenario where Django parses an XML document describing allowed scopes and uses a value from the bearer token to select a node:
from lxml import etree
import os
xml_data = os.readfile('policies.xml')
root = etree.fromstring(xml_data)
# Dangerous: concatenating token-derived value into XPath
token_scope = request.META.get('HTTP_AUTHORIZATION', '').replace('Bearer ', '')
expr = f"//scope[@name='{token_scope}']/permissions"
permissions = root.xpath(expr)
An attacker who controls the bearer token can change the intended node selection, retrieve unintended elements, or cause errors that leak internal structure. This is a classic case of injection via XPath combined with misuse of bearer token data. The unauthenticated attack surface tested by middleBrick includes such input validation and data exposure checks, which can detect unsafe usage patterns where external inputs influence XML navigation logic.
Additionally, if your Django application exposes an endpoint that returns runtime information (e.g., introspection or debug data) and that endpoint uses XPath queries built from request-derived identifiers, an attacker may leverage malformed tokens or parameters to probe the XML structure. This aligns with BOLA/IDOR and Input Validation checks that middleBrick runs in parallel, flagging endpoints where object-level authorization or input sanitization is insufficient. MiddleBrick’s scans do not rely on internal architecture but surface these risky patterns by correlating spec definitions with observed runtime behavior, including cases where bearer tokens appear in request headers and affect document selection.
Bearer Tokens-Specific Remediation in Django — concrete code fixes
To prevent XPath Injection when bearer tokens or any external data influence XML queries, avoid string concatenation or interpolation. Use parameterized XPath expressions where the parser supports variables, or sanitize inputs strictly. Below is a safe approach using lxml’s XPath support with variable binding:
from lxml import etree
xml_data = b'''<root>
<scope name="read">
<permissions>view</permissions>
</scope>
<scope name="write">
<permissions>view edit delete</permissions>
</scope>
</root>'''
root = etree.fromstring(xml_data)
# Safe: use variable binding instead of string interpolation
token_scope = 'read' # This would come from validated source, not raw token
permissions = root.xpath('//scope[@name=$scope]/permissions', scope=token_scope)
print(permissions) # Expected output: ['view']
If you must construct expressions dynamically for compatibility reasons, rigorously validate and whitelist allowed values. For bearer tokens, do not directly embed the token string; instead map it to a controlled scope or role via a lookup table:
VALID_SCOPES = {'read', 'write', 'admin'}
user_scope = extract_scope_from_token(token) # Your mapping logic
if user_scope not in VALID_SCOPES:
raise ValueError('Invalid scope')
# Use whitelisted value in XPath
expr = '//scope[@name=$scope]/permissions'
permissions = root.xpath(expr, scope=user_scope)
When integrating with authentication libraries, ensure token handling does not inadvertently expose data used in XPath queries. MiddleBrick’s CLI can scan your Django project to surface places where request headers or tokens reach XML processing logic without adequate validation. If you use the GitHub Action, you can add API security checks to your CI/CD pipeline and fail builds if risky patterns are detected. For continuous monitoring, the Pro plan supports scheduled scans and alerts, helping you catch regressions early.
Additionally, apply defense in depth: enforce strict input validation on any data entering XML queries, use least privilege when accessing documents, and avoid exposing internal XML structures in error messages. The MCP Server allows you to scan APIs directly from your AI coding assistant, which can help you review code snippets during development before they reach production.