Our website uses cookies to enhance your browsing experience.
Accept
to the top
close form

Fill out the form in 2 simple steps below:

Your contact information:

Step 1
Congratulations! This is your promo code!

Desired license type:

Step 2
Team license
Enterprise license
** By clicking this button you agree to our Privacy Policy statement
close form
Request our prices
New License
License Renewal
--Select currency--
USD
EUR
* By clicking this button you agree to our Privacy Policy statement

close form
Free PVS‑Studio license for Microsoft MVP specialists
* By clicking this button you agree to our Privacy Policy statement

close form
To get the licence for your open-source project, please fill out this form
* By clicking this button you agree to our Privacy Policy statement

close form
I am interested to try it on the platforms:
* By clicking this button you agree to our Privacy Policy statement

close form
check circle
Message submitted.

Your message has been sent. We will email you at


If you do not see the email in your inbox, please check if it is filtered to one of the following folders:

  • Promotion
  • Updates
  • Spam

Webinar: Evaluation - 05.12

>
>
>
V5622. OWASP. Possible XPath injection.…
menu mobile close menu
Analyzer diagnostics
General Analysis (C++)
General Analysis (C#)
General Analysis (Java)
Micro-Optimizations (C++)
Diagnosis of 64-bit errors (Viva64, C++)
Customer specific requests (C++)
MISRA errors
AUTOSAR errors
OWASP errors (C++)
OWASP errors (C#)
Problems related to code analyzer
Additional information
toggle menu Contents

V5622. OWASP. Possible XPath injection. Potentially tainted data is used in the XPath expression.

May 11 2022

The analyzer has detected unverified external data used to form the XPath expression. This can cause an XPath Injection.

Vulnerabilities related to injections belong to the OWASP Top 10 Application Security Risks: A3:2021-Injection.

Look at the example:

class UserData
{
  HttpRequest request;
  XPathNavigator navigator;

  void RetrieveUserData()
  {
    string username = request.Form["username"];
    string password = request.Form["password"];
    string hashedPassword = Hash(password);
    
    string query = $@"//users/user[
                      username/text() = '{username}' and
                      passwordHash/text() = '{hashedPassword}']
                      /data/text()";
    
    object res = navigator.Evaluate(query);
    ....
  }
}

In this example, the XPath expression is used to get user data from an XML file. The username is stored "as is" and the password is stored encrypted.

An attacker can pass any data as a username and password. The check will be compromised, if an expression that makes the XPath condition always true is passed in the input data. Since the password is stored in an encrypted form, the unsafe expression should be injected together with the username.

For example, let the username be 'john'. To the username, let's append an expression of the following type:

' or ''='

Any set of characters can be entered instead of a password. Then the XPath expression will look as follows:

[
  username/text()='john' or ''='' and
  passwordHash/text() = '750084105bcbe9d2c89ba9b'
]

Now the expression contains the 'or' operator. Let's consider how the expression is evaluated:

  • Since this username exists, the expression "username/text()='john'" is true.
  • Random characters were entered as a password, so the PasswordHash/text() = '750084105bcbe9d2c89ba9b' expression is false.
  • The "=" expression is always true.
  • The priority of the 'and' operator is higher than 'or', so the "=" and PasswordHash/text() = '750084105bcbe9d2c89ba9b' expression is evaluated. The result is false.
  • The 'or' operator is last to be executed. The "username/text()='john' or false" expression is true. Consequently, the whole condition is true.

Thus, the result of the XPath query will be the user data of 'john' regardless of whether the correct password was entered or not. This can lead to data leakage.

Do not use unverified external data in XPath expressions. To increase security, it is worth escaping potentially dangerous characters in external data. Examples of such characters are "<", ">" and "'". Escaping may be performed with the 'SecurityElement.Escape' method:

class UserData
{
  HttpRequest request;
  XPathNavigator navigator;
  void RetrieveUserData()
  {
    string username = request.Form["username"];
    string password = request.Form["password"];
    username = SecurityElement.Escape(username);
    string hashedPassword = Hash(password);
    string query = $@"//users/user[
                      username/text()= '{username}' and 
                      passwordHash/text() ='{hashedPassword}']
                      /data/text()";
    
    object res = navigator.Evaluate(query);
    ....
  }
}

There are other ways to prevent XPath injections. For example, Microsoft suggests implementing a resolver class. This class may be used in methods of the 'XPathNavigator' class. These methods accept the XPath expression's string and the object that implements the 'IXmlNamespaceResolver' interface.

Inside the XPath expression, you can set custom variables and functions that will be processed by the resolver. This approach is not a solution to the XPath injection problem. However, setting custom variables allows to use an approach similar to the parameterization of SQL queries.

In addition, the analyzer considers methods' parameters from other assemblies to be unsafe sources. This topic is covered in more detail in the following article: "Why you should check values of public methods' parameters". Look at the example:

public class UserData
{
  XPathNavigator navigator;
  public object RetrieveUserData(string username,
                                 string password)
  {
    string hashedPassword = Hash(password);
    string query = $@"//users/user[
                     username/text()= '{username}' and 
                     passwordHash/text() = '{hashedPassword}']
                     /data/text()";
    
    return EvaluateXpath(query);
  }
  
  private object EvaluateXpath(string xpath)
  {
    object res = navigator.Evaluate(xpath);
    ....
  }
}

In this example, the 'RetrieveUserData' method can be called from other assemblies. The 'username' and 'password' parameters of this method are not checked before use in the XPath query. The resulting expression in the 'query' variable is passed to the 'EvaluateXpath' method. In the method, the expression is used without a prior check. In this case, the analyzer will issue a warning of low level of certainty.

This diagnostic is classified as: