Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft Jtest 2022.2

Due to its platform independence, flexibility and relative simplicity, extensible markup language (XML) has been widely adopted in a wide variety of applications, from remote procedure calls to data storage. However, because of its versatility, XML is vulnerable to attacks which change the structure of the document. One such attack is XML injection (MSC36-J. Prevent XML Injection), in which XML tags are injected directly into data fields. A variant of this is is XPath injection, in which the attacker manipulates a query into an XML-specified document.

XPath injection occurs when an XML document is used for data storage in a manner similar to a relational database. This way, an XPath injection is similar to an SQL injection attack (MSC34-J. Prevent against SQL Injection), where an attack is able to include query logic in a data field in such a way the the Extensible Markup Language (XML) can be used for data storage in a manner similar to a relational database. Data is frequently retrieved from such an XML document using XPaths. XPath injection can occur when data supplied to an XPath retrieval routine to retrieve data from an XML document is used without proper sanitization. This attack is similar to SQL injection or XML injection (see IDS00-J. Sanitize untrusted data passed across a trust boundary). An attacker can enter valid SQL or XML constructs in the data fields of the query in use. In typical attacks, the conditional field of the query resolves as to a tautology or otherwise gives the attacker access to information it should not be entitled to.

...

privileged information.

This guideline is a specific example of the broadly scoped IDS52-J. Prevent code injection.

XML Path Injection Example

Consider the following XML document being used as a databaseschema:

No Formatcode

<users>
  <user>
    <login>Utah<<username>Utah</login>username>
    <password>test123<<password>e90205372a3b89e2</password>
  </user>
  <user>
    <login>Bohdi<<username>Bohdi</login>username>
    <password>password<<password>6c16b22029df4ec6</password>
  </user>
  <user>
    <login>Busey<<username>Busey</login>username>
    <password>abc123<<password>ad39b3c2a4dabc98</password>
  </user>
</users>

The passwords are hashed in compliance with MSC62-J. Store passwords using a hash function. MD5 hashes are shown here for illustrative purposes; in practice, you should use a safer algorithm such as SHA-256.

Untrusted code may Unsafe code will attempt to retrieve a user details from this file with an XPath statement constructed dynamically from user input.

Code Block
No Format

str_query = "//users/user[LoginIDusername/text()= " & login & 
            "'&LOGIN&' and password/text()=" & password & "]"

Therefore, the user may specify input such as login = "' or 1=1" and password = "' or 1=1", yielding the following query string:

'&PASSWORD&' ]

If an attacker knows that Utah is a valid user name, he or she can specify an input such as

Code Block
Utah' or '1'='1

This yields the following query string.

Code Block
No Format

//users/user[LoginIDusername/text()='Utah' or '1'='1 ' and password/text()='' or 1=1]

This will subsequently reveal all the records in the XML file

Noncompliant Code Example

XML Injection may occur when:

  • Data is read from an untrusted source (such as user input)
  • Data is subsequently written to an XPath query string without proper sanitization.
xxxx']

Because the '1'='1' is automatically true, the password is never validated. Consequently, the attacker is inappropriately authenticated as user Utah without knowing Utah's password.

Noncompliant Code Example

This noncompliant code example reads a user name and password from the user and uses them to construct the query string. The password is passed as a char array and then hashed. This example is vulnerable to the attack described earlier. If the attack string described earlier is passed to evaluate(), the method call returns the corresponding node in the XML file, causing the doLogin() method to return true and bypass any authorizationConsider the following example in which a login and password are read from the user and used to construct the query string, in the context of the attack illustrated above.

Code Block
bgColor#FFcccc


                
import java.io.IOException;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.*;
import javax.xml.xpath.*;

public class XpathInjectionExample {

  
       publicprivate boolean doLogin(String loginIDuserName, Stringchar[] password)
             throws ParserConfigurationException, SAXException, IOException, 
XPathExpressionException {

          DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
         domFactory.setNamespaceAware(true);
         DocumentBuilder builder = domFactory.newDocumentBuilder();
         Document doc = builder.parse("users.xml");

  String pwd =   hashPassword( password);

  XPathFactory factory = XPathFactory.newInstance();
         XPath xpath = factory.newXPath();
         XPathExpression expr = xpath.compile("//users/user[loginusername/text()='" + 
           userName + loginID +"'" + "and password/text()='" +password pwd + "' ]")";
     Object result = expr.evaluate(doc, XPathConstants.NODESET);
         NodeList nodes = (NodeList) result;

  //print Print first names to the console 
         for (int i = 0; i < nodes.getLength(); i++) {
    Node node        System.out.println(nodes= nodes.item(i).getChildNodes().item(i1).getNodeValuegetChildNodes().item(0);}
    System.out.println( "Authenticated: " + node.getNodeValue());
     
       }

         if return (nodes.getLength() >= 1) {               
              return true;}
              else
             {return false;}
       }
}

The evaluate function call will return a set of all nodes in the XML file, causing the login function to return true, and bypassing authorization.

...

Compliant Solution (XQuery)

XPath injection can be prevented with many of the same methods by adopting defenses similar to those used to prevent SQL injection, and input sanitization in general. These methods include:

  • Assume Treat all input may include an attackuser input as untrusted, and perform appropriate sanitization.
  • When validating sanitizing user input, verify the correctness of the data type, length, format, and contentscontent. For example, construct use a regular expression that checks for XML tags and special characters in user input. This practice corresponds to input sanitization. See IDS52-J. Prevent code injection for additional details.
  • In a client-server application, perform validation at both the client and the server sides.
  • Extensively test applications which that supply, propagate, or accept user input.

In similar vulnerabilities such as SQL injection, the best practice to avoid injection vulnerabilities is to use a technique called parameterization, in which An effective technique for preventing the related issue of SQL injection is parameterization. Parameterization ensures that user-specified data is passed directly to an API as a parameter , which in turn ensures that no data specified by the user is interpreted as execution logic. Unfortunately, such an interface does not currently exist in Java. However, this functionality such that the data is never interpreted as executable content. Unfortunately, Java SE currently lacks an analogous interface for XPath queries. However, an XPath analog to SQL parameterization can be emulated by using an interface such as XQuery , which enables the user to effectively parameterize data by specify that supports specifying a query statement in a separate file , and only specify data supplied at runtime. Consider the example illustrated above, the following query specified in a text file, and the following source code.

Input File: login.qry

No Formatcode

declare variable $loginID$userName as xs:string external;
declare variable $password as xs:string external;
//users/user[@loginID@userName=
$loginID$userName and @password=$password]

Source CodeThis compliant solution uses a query specified in a text file by reading the file in the required format and then inserting values for the user name and password in a Map. The XQuery library constructs the XML query from these inputs.

Code Block
bgColor#ccccff


Document doc = new Builder().buildprivate boolean doLogin(String userName, String pwd)
  throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {

  DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
  domFactory.setNamespaceAware(true);
  DocumentBuilder builder = domFactory.newDocumentBuilder();
  Document doc = builder.parse("users.xml");

  XQuery xquery = new XQueryFactory().createXQuery(new File(" 
dologinlogin.xq"));

  Map queryVars = new HashMap();

  queryVars.put("loginiduserName", "Utah"userName);
  queryVars.put("password", "test123"pwd);

Nodes results  NodeList nodes = xquery.execute(doc, null, varsqueryVars).toNodes();

  // Print first names to the console
  for (int i = 0; i < resultsnodes.sizegetLength(); i++) {
    Node node = nodes.item(i).getChildNodes().item(1).getChildNodes().item(0);
    System.out.println(resultsnode.getgetNodeValue(i).toXML()));
  }

  return (nodes.getLength() >= 1);
}

Using this method, the data specified in loginID and password will not the userName and password fields cannot be interpreted as executable expressions content at runtime.

...

Applicability

Failing Failure to validate user input may result in a Java application being seriously compromised. Information disclosure is possible, but most likely the attacker will be able to modify sensitive information, such as in the example above in which the attacker modifies the data in the price field. In certain cases, such as a table representing users and privileges, the attacker could be able to modify information about their user account that would allow them to run code with elevated privileges.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MSC36-J-J

medium

medium

medium

P4

L3

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Fortify Software VulnCat

IBM DeveloperWorks

Sun Microsystems Java Developer Network

information disclosure and execution of unprivileged code.

According to OWASP [OWASP 2014],

[Prevention of XPath injection] requires the following characters to be removed (that is, prohibited) or properly escaped:

  • < > / ' = " to prevent straight parameter injection.
  • XPath queries should not contain any meta characters (such as ' = * ? // or similar).
  • XSLT expansions should not contain any user input, or if they do, [you should] comprehensively test the existence of the file, and ensure that the files are within the bounds set by the Java 2 Security Policy.

Automated Detection

ToolVersionCheckerDescription
The Checker Framework

Include Page
The Checker Framework_V
The Checker Framework_V

Tainting CheckerTrust and security errors (see Chapter 8)
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.IDS53.TDJXPATH
CERT.IDS53.TDXPATH
Protect against JXPath injection
Protect against XPath injection

Bibliography


...

Image Added Image Added Image AddedOWASP