This article explains XPath injection, an attack that exploits how web applications build XPath queries from user input to authenticate against XML user stores. The lab demonstrates how an attacker can inject XPath syntax into a login form to bypass password verification and gain unauthorized access, mirroring the structural risks of SQL injection but targeting XML query languages instead.
- XPath injection exploits string concatenation in queriesApplications that build XPath expressions by directly concatenating user input allow attackers to inject XPath operators and syntax that rewrite the query logic. When credentials are looked up via an XPath query like 'select the user whose name and password both match', an attacker can send XPath syntax in the username or password field to change which nodes the query selects, typically making the password condition always true and selecting the admin node regardless of the actual password.
- Attack neutralizes password condition with logicThe core technique involves submitting the admin username combined with XPath syntax that collapses the password comparison into an always-true statement. This is accomplished by using XPath operators or quotes to transform the AND logic between username and password checks, so the expression selects the target node based on username alone, bypassing password validation entirely.
- Root cause identical to SQL injection patternsXPath injection is structurally the same vulnerability as SQL injection—untrusted user input is concatenated directly into a query language without parameterization or escaping. The only difference is the query language involved: XPath over XML instead of SQL, making it fall under the Injection category (A03) in the OWASP Top 10 (2021).
- Parameterized XPath with variable binding prevents injectionThe primary defense is using parameterised XPath (variable binding) so user data is never interpreted as query syntax. If parameterisation is unavailable, input must be strictly escaped and validated before being concatenated into an expression, and credentials should be stored in a proper datastore with hashing rather than matched inside an XML query itself.
- Detection indicator: quotes and brackets change resultsIf stray quotes or brackets in login or search input produce different results, the application is likely concatenating user input into an XPath expression. This behavioral indicator helps identify vulnerable systems in real-world assessments.
- Affects XML-backed authentication and older SOAP servicesXPath injection appears in applications that authenticate or search against XML documents by building queries from user input, with typical victims being older SOAP services and XML-backed login systems that have not moved to parameterised query patterns.
- Generic error messages reduce attacker feedbackReturning generic authentication error messages (rather than indicating whether a username or password failed) prevents attackers from using error responses to confirm successful injection or refine their payloads during an attack.
Bottom line: XPath injection is a direct parallel to SQL injection: it exploits concatenation of untrusted input into a query language, and it is prevented by using parameterised queries with variable binding rather than string concatenation. Understanding this vulnerability is critical because any application building XPath, SQL, LDAP, or similar queries from user input faces identical injection risks if proper parameterisation is not employed.
📋 In this walkthrough
What this lab teaches
XPath injection targets apps that query XML with XPath built from user input. By injecting XPath syntax, an attacker rewrites the query's logic — classically turning a username-and-password lookup into one that matches a node regardless of the password.
The lesson: XML is data, and XPath over it is a query language with the same injection risk as SQL when it is built by string concatenation.
How XmlAuth looks users up
XmlAuth builds an XPath expression meaning 'select the user whose name and password both match', inserting your values straight into the expression. Your input is parsed as part of the XPath, so XPath operators you send change which nodes the expression selects.
The attack approach
- Notice authentication is an XPath query over an XML user store.
- Inject XPath syntax so the password part of the condition is always satisfied.
- Steer the expression to select the admin node on the username alone.
- Submit and gain the admin session.
Full walkthrough (spoiler)
If the query still fails to match, the condition is not closing correctly — open the steps.
Show the step-by-step solution
- In the login fields, supply the admin username plus XPath syntax that neutralises the password condition.
- Use an always-true comparison so the AND between username and password resolves on the username alone.
- Submit. The XPath now selects the admin node regardless of the password value.
- You are authenticated as admin and the lab marks you solved.
Why it works
The application assumes your input is a plain value, but it is concatenated into an XPath expression. XPath operators and quotes you send are interpreted as query logic, so the password comparison collapses into something always true and the admin node is selected.
Where this happens in the real world
XPath injection appears wherever apps authenticate or search against XML documents by concatenating input into a query — older SOAP services and XML-backed logins are typical. It is structurally identical to SQL injection and falls under Injection (A03) in the OWASP Top 10 (2021).
How to defend against it
- Use parameterised XPath (variable binding) so user data never becomes query syntax.
- Escape and validate input if you must build expressions as strings.
- Store credentials properly (hashed, in a real datastore) rather than matching passwords inside an XML query.
- Return generic auth errors so injection attempts get no extra feedback.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own approach before peeking at the spoiler, and see how many attempts it takes.
