|
| 1 | +== How to fix it in Java XML API |
| 2 | + |
| 3 | +=== Code examples |
| 4 | + |
| 5 | +The following noncompliant code is vulnerable to XPath injections because untrusted data is |
| 6 | +concatenated to an XPath query without prior validation. |
| 7 | + |
| 8 | +==== Noncompliant code example |
| 9 | + |
| 10 | +[source,kotlin,diff-id=1,diff-type=noncompliant] |
| 11 | +---- |
| 12 | +import javax.xml.xpath.XPath |
| 13 | +import javax.xml.xpath.XPathConstants |
| 14 | +
|
| 15 | +fun authenticate(request: HttpServletRequest, xpath: XPath, doc: Document): Boolean { |
| 16 | + val user: String = request.getParameter("user") |
| 17 | + val pass: String = request.getParameter("pass") |
| 18 | + val expression = "/users/user[@name='$user' and @pass='$pass']" |
| 19 | + return xpath.evaluate(expression, doc, XPathConstants.BOOLEAN) as Boolean |
| 20 | +} |
| 21 | +---- |
| 22 | + |
| 23 | +==== Compliant solution |
| 24 | + |
| 25 | +[source,kotlin,diff-id=1,diff-type=compliant] |
| 26 | +---- |
| 27 | +import javax.xml.xpath.XPath |
| 28 | +import javax.xml.xpath.XPathConstants |
| 29 | +import javax.xml.xpath.XPathVariableResolver |
| 30 | +
|
| 31 | +fun authenticate(request: HttpServletRequest, xpath: XPath, doc: Document?): Boolean { |
| 32 | + val user = request.getParameter("user") |
| 33 | + val pass = request.getParameter("pass") |
| 34 | + val expression = "/users/user[@name=\$user and @pass=\$pass]" |
| 35 | + xpath.xPathVariableResolver = XPathVariableResolver { v: QName -> |
| 36 | + when (v.localPart) { |
| 37 | + "user" -> return@XPathVariableResolver user |
| 38 | + "pass" -> return@XPathVariableResolver pass |
| 39 | + else -> throw IllegalArgumentException() |
| 40 | + } |
| 41 | + } |
| 42 | + return xpath.evaluate(expression, doc, XPathConstants.BOOLEAN) as Boolean |
| 43 | +} |
| 44 | +---- |
| 45 | + |
| 46 | +=== How does this work? |
| 47 | + |
| 48 | +As a rule of thumb, the best approach to protect against injections is to |
| 49 | +systematically ensure that untrusted data cannot break out of the initially |
| 50 | +intended logic. |
| 51 | + |
| 52 | +include::../../common/fix/parameterized-queries.adoc[] |
| 53 | + |
| 54 | +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. |
| 55 | + |
| 56 | +include::../../common/fix/validation.adoc[] |
| 57 | + |
| 58 | +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. |
0 commit comments