XPath Injection
XML Path Language (XPath) is a query language for Extensible Markup Language (XML) data. Specifically, we can use XPath to construct XPath queries for data stored in the XML format. Like SQL injection
Last updated
XML Path Language (XPath) is a query language for Extensible Markup Language (XML) data. Specifically, we can use XPath to construct XPath queries for data stored in the XML format. Like SQL injection
Last updated
Automatic tool: xcat, or other options
We aim to bypass authentication by injecting a username and password such that the XPath query always evaluates to true . We can achieve this by injecting the value ' or '1'='1 as username and password. The resulting XPath query looks like this:
from originally:
Since the predicate evaluates to true , the query returns all user element nodes from the XML document. Therefore, we are logged in as the first user. In our example document, this is the user example. However, what if we want to log in as the admin user to obtain the highest permissions? In that case, we have to inject a username of admin' or '1'='1 and an arbitrary value for the password. That way, the resulting XPath query looks like this:
In real-world scenarios, passwords are often hashed. Additionally, we might not know a valid username, therefore, we cannot use the abovementioned payloads. Fortunately, we can use more advanced injection payloads to bypass authentication in such cases.
Firstly, we can inject a double or clause in the username to make the XPath query return true , thereby returning all user nodes such that we log in as the first user. An example payload would be
' or true() or '
resulting in the following query:
Due to the way the query is evaluated, the double or results in a universal true returned by the query, so we bypass the authentication. However, just like discussed previously, we might want to log in as a specific user to obtain more privileges.
One way to do this is to iterate over all users by their position. This can be achieved with the following payload:
' or position()=2 or '
, resulting in the following query:
This will return only the second user node. We can increment the position to iterate over all users until we find the user we seek. There might be millions of users in real-world deployments, thus, this manual technique will become infeasible very quickly. Instead, we can search for specific users if we know part of the username. For this, consider the following payload:
' or contains(.,'admin') or '
, resulting in the following query:
This query returns all user nodes that contain the string admin in any descendants. Since the username node is a child of the user node, this returns all users that contain the substring admin in the username.
The simplest is probably to append a new query that returns all text nodes. We can do this with a request like this:
The web application will then execute the following query:
We could also achieve the same result by using this payload in the q parameter: SOMETHINGINVALID') or ('1'='1 and setting the f parameter to ../../..//text() . This would result in the following XPath query:
Advanced Data Exfiltrating
Just read the document, probably a tool or a script you can make.