Remote Code Execution in JXPath Library (CVE-2022-41852)
On 6th October 2022 new CVE was released for critical vulnerability with identifier CVE-2022-41852. This vulnerability
affects Java library called Apache Commons JXPath, which is used for processing XPath syntax.
All versions (including latest version) are affected by this vulnerability.
According to NIST the vulnerability score is 9.8 CRITICAL with CVSS:
Currently there is no official fix for this vulnerability, but we might have a solution that should protect the application, however it will disable use of functions in all XPaths completely.
Are You Vulnerable?
If your application uses JXPath library (artifact commons-jxpath:commons-jxpath), you might be vulnerable. According to CVE information, all methods for XPath processing are vulnerable, except for except compile() and compilePath(). If user can provide value for the XPath expression, it might allow him to execute code on your application server (in application context).
Version: <= 1.3
If you use SCA (Software Composition Analysis) tools like OWASP Dependency Check, BlackDuck, CxSCA and others, they will probably notify you about this vulnerability automatically.
Proof of Concept
First, let’s look at the proof of concept that I created for this vulnerability on simple Spring framework application. The PoC contains just simple vulnerable endpoint method that takes user input and uses it to retrieve specified data from Person class. Valid user inputs for this endpoint are “author”, “name” and “/”.
If we call this endpoint with query string ?path=website, it will return the person’s website:
However, attacker can send malicious input with Java code. For example, we can send query string:
This will cause the application to exit. See the following Spring application log:
There might be use cases, where the user’s input is prefixed / suffixed by the application. For example, there might be preceding slash character (/):
But that does not stop the attacker, because he can simply utilize XPath pipe and send query string (note: %7C is encoded pipe character):
This payload will also cause the application to crash.
Ok, now we know, how to kill the application server. However, how to run commands on the server? There might be lots of ways that will allow attacker to execute commands on the server. One of them is taking advantage of Spring's ClassPathXmlApplicationContext, which allows loading beans using XML configuration.
Our payload will load external XML file from our server:
The XML file will contain configuration for creation of bean from Java's ProcessBuilder with parameters for running calculator using CMD on Windows:
This simple exploit will open calculator on our Windows server:
How to check if some parameter is vulnereable? If you are a pentester and you want to test applications for this vulnerability, these payloads might be helpful:
Of course, you can create your own payloads. Official documentation might be helpful, see the chapter bellow.
It’s Not a Bug It’s a Feature
What is more interesting is that the above described vulnerability is actually a feature of the JXPath library. You can even find users guide for this feature, which describes that we can use fully qualified class name to call functions:
Currently, the library does not have secure version. I have seen opened pull request on JXPath GitHub (see https://github.com/apache/commons-jxpath/pull/26), which adds function-filtering options. However, if you have the library in your project and user can affect at least part of XPath, there is currently no official solution.
I have a solution that might work for some of you, however, it comes with a cost – no functions will work in XPath expressions. So, if you use functions like size() in our XPath expressions, this solution will not be good for you.
How the partial solution works? During code analysis of JXPath library, I have found that there is the following code in JXPathContext class for creating GENERIC_FUNCTIONS constant. This constant is used as default value if no Functions object is specified:https://github.com/apache/commons-jxpath/pull/26
The code above allows all functions from all packages to be called. If we want to prevent this default to be used, we can specify our own Functions object. For that, we can use empty FunctionLibrary:
Using pathContext.setFunctions(new FunctionLibrary()); we replace the default with empty function library, so the exploit payloads mentioned above will not work. Sending one of the payloads will lead to JXPathFunctionNotFoundException.
If your application is affected, consider using the mentioned solution above. If this solution does not fit your needs, because you need the XPath functions to work, you will have to wait for new release of this library with potential fix (note that the library was not released for a long time) or wait for new solutions to arise.