Why is this an issue?
XPath injections occur in an application when the application retrieves untrusted data and inserts it into an XML Path (XPath) query without
sanitizing it first.
What is the potential impact?
In the context of a web application vulnerable to XPath injection:
After discovering the injection point, attackers insert data into the
vulnerable field to execute malicious commands in the affected XML documents.
The impact of this vulnerability depends on the importance of XML structures in the enterprise.
In cases where organizations rely on XML
structures for business-critical operations or where XML is used only for innocuous data transport, the severity of an attack ranges from critical to
harmless.
Below are some real-world scenarios that illustrate some impacts of an attacker exploiting the vulnerability.
Data Leaks
A malicious XPath query allows direct data leakage from one or more databases. Although XML is not as widely used as it once was, this possibility
still exists with configuration files, for example.
Data deletion and denial of service
The malicious query allows the attacker to delete data in the affected XML documents.
This threat is particularly insidious if the attacked
organization does not maintain a disaster recovery plan (DRP) and if XML structures are considered important, as missing critical data can disrupt the
regular operations of an organization.
How to fix it in .NET
Code examples
The following code is vulnerable to XPath injections because untrusted data is concatenated in an XPath query without prior validation.
Noncompliant code example
public class ExampleController : Controller
{
[HttpGet]
public IActionResult Authenticate(string user, string pass)
{
XmlDocument doc = new XmlDocument();
String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']";
return Json(doc.SelectSingleNode(expression) != null);
}
}
Compliant solution
public class ExampleController : Controller
{
[HttpGet]
public IActionResult Authenticate(string user, string pass)
{
XmlDocument doc = new XmlDocument();
if (!Regex.IsMatch(user, "^[a-zA-Z]+$") || !Regex.IsMatch(pass, "^[a-zA-Z]+$"))
{
return BadRequest();
}
String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']";
return Json(doc.SelectSingleNode(expression) != null);
}
}
How does this work?
As a rule of thumb, the best approach to protect against injections is to systematically ensure that untrusted data cannot break out of the
initially intended logic.
Validation
In case XPath parameterized queries are not available, the most secure way to protect against injections is to validate the input before using it
in an XPath query.
Important: The application must do this validation server-side. Validating this client-side is insecure.
Input can be validated in multiple ways:
- By checking against a list of authorized and secure strings that the application is allowed to use in a query.
- By ensuring user input is restricted to a specific range of characters (e.g., the regex
/^[a-zA-Z0-9]*$/
only allows alphanumeric
characters.)
- By ensuring user input does not include any XPath metacharacters, such as
"
, '
, /
, @
,
=
, *
, [
, ]
, (
and )
.
If user input is not considered valid, it should be rejected as it is unsafe.
In the example, a validation mechanism is applied to untrusted input to ensure it is strictly composed of alphabetic characters.
Resources
Articles & blog posts
Standards