Our website uses cookies to enhance your browsing experience.
Accept
to the top
>
>
>
V5312. 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#)
OWASP errors (Java)
Problems related to code analyzer
Additional information
toggle menu Contents

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

Feb 04 2025

The analyzer has detected that unverified external data is used to create an XPath expression. This can result in an XPath injection.

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

Look at the following example:

public class UserData {
    HttpServletRequest request;
    MessageDigest digest;
    Document doc;

    public void retrieveUserData() {
        String user = request.getParameter("username");
        String password = request.getParameter("password");
        String passwordHash = Arrays.toString(
                digest.digest(password.getBytes(StandardCharsets.UTF_8))
        );
        var xpath = XPathFactory.newInstance().newXPath();

        String query = "//users/user[" +
                "username/text() = '%s' and" +
                "passwordHash/text() = '%s']" +
                "/data/text()";
        query = String.format(query, user, passwordHash);

        try {
            String result = xpath.evaluate(query, doc);
            // ....
        } catch (XPathExpressionException e) {
            // ....
        }
        //....
    }
}

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

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

Let's say the username is john and add the following expression to it:

' or ''='

You can enter any characters instead of a password. Then, the XPath expression will look like this:

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

Now the expression contains the or operator. Let's look at how it is evaluated:

  • Since the username exists, the username/text()='john' expression is true.
  • Random characters were entered as the password, so the passwordHash/text() = '750084105bcbe9d2c89ba9b' expression is false.
  • The ''='' expression is always true.
  • The and operator has a higher priority than or, so the ''='' and passwordHash/text() = '750084105bcbe9d2c89ba9b' expression is evaluated. The result is false.
  • The or operator executes last. The username/text()='john' or false expression is true. So, the entire condition is true.

Thus, the result of the XPath query is the john user data, regardless of whether the password is correct or not. This can lead to a data breach.

Do not use unverified external data in XPath expressions. To improve security, it is better to escape potentially dangerous characters in external data. The <, >, and ' are examples of such symbols. Escaping can be done via simple replaceAll:

public class UserData {
    HttpServletRequest request;
    MessageDigest digest;
    Document doc;

    public void retrieveUserData() {
        String user = request.getParameter("username")
                .replaceAll("'", "&abos;");
        String password = request.getParameter("password");
        String passwordHash = Arrays.toString(
                digest.digest(password.getBytes(StandardCharsets.UTF_8))
        );
        var xpath = XPathFactory.newInstance().newXPath();

        String query = "//users/user[" +
                "username/text() = '%s' and" +
                "passwordHash/text() = '%s']" +
                "/data/text()";
        query = String.format(query, user, passwordHash);

        try {
            String result = xpath.evaluate(query, doc);
            // ....
        } catch (XPathExpressionException e) {
            // ....
        }
        //....
    }
}

Apache Commons Text also contains the StringEscapeUtils utility class, two methods of which are escapeXml10 and escapeXml11. All necessary characters can be escaped using these methods.

There are other ways to prevent XPath injections. For example, Oracle suggests implementing a resolver class. You can use it in XPath class objects. In the XPath expression, you can set user-defined variables and functions to be processed by the resolver.

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