== How to fix it in Java SE

=== Code examples

The following noncompliant code is vulnerable to XPath injections because untrusted data is
concatenated to an XPath query without prior validation.

==== Noncompliant code example

[source,java,diff-id=1,diff-type=noncompliant]
----
public boolean authenticate(HttpServletRequest req, XPath xpath, Document doc) throws XPathExpressionException { 
  String user = request.getParameter("user"); 
  String pass = request.getParameter("pass");

  String expression = "/users/user[@name='" + user + "' and @pass='" + pass + "']";

  return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN);
}
----

==== Compliant solution

[source,java,diff-id=1,diff-type=compliant]
----
public boolean authenticate(HttpServletRequest req, XPath xpath, Document doc) throws XPathExpressionException { 
  String user = request.getParameter("user"); 
  String pass = request.getParameter("pass");

  String expression = "/users/user[@name=$user and @pass=$pass]";

  xpath.setXPathVariableResolver(v -> {
    switch (v.getLocalPart()) {
      case "user":
        return user;
      case "pass":
        return pass;
      default:
        throw new IllegalArgumentException();
    }
  });

  return (boolean)xpath.evaluate(expression, doc, XPathConstants.BOOLEAN);
}

----

=== 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.

include::../../common/fix/parameterized-queries.adoc[]

In the example, a parameterized XPath query is created, and an `XPathVariableResolver` is used to securely insert untrusted data into the query, similar to parameterized SQL queries.

include::../../common/fix/validation.adoc[]

For Java, OWASP's Enterprise Security API offers https://www.javadoc.io/doc/org.owasp.esapi/esapi/latest/org/owasp/esapi/Encoder.html#encodeForXPath-java.lang.String-[`encodeForXPath`] which sanitizes metacharacters automatically.
