Apache XML-RPC is a XML-RPC library for Java. XML-RPC is a protocol for making remote procedure call via HTTP with the help of XML. Apache XML-RPC can be used on the client’s side to make XML-RPC calls as well as on the server’s side to expose some functionality via XML-RPC.

Now ws-xmlrpc library is not supported by Apache. Last version is 3.1.3 which was released in 2013. However, many applications still use ws-xmlrpc library. Among them are Apache Continuum and Apache Archiva.  Apache Continuum project have been moved to the Attic not long ago. But Apache Archiva is alive.

Recently I performed security assessment for Java project which had XML-RPC endpoint on /xmlrpc path. I figured out that the project used ws-xmlrpc library, and I started to dig into ws-xmlrpc to find something interesting. Finally I’ve found three vulnerabilities in ws-xmlrpc library and reported them to Apache Security Team. Because ws-xmlrpc is not supported, they have assigned following CVE numbers for Apache Archiva: CVE-2016-5002, CVE-2016-5003, and CVE-2016-5004.

To demonstrate how these vulnerabilities in ws-xmlrpc library can be abused, I wrote simple application unsafe-xmlrpc with XML-RPC functionality. To play with it, you should deploy it on your favorite servlet container, e.g. Apache Tomcat.

This application exposes functionality of Echo method of Echo class via XML-RPC. If you issue POST request to /unsafe-xmlrpc/xmlrpc and pass <methodCall> request, you will get the response with the result of Echo method invocation as shown on the screenshot.

Vulnerability CVE-2016-5004 can be abused to perform DoS attacks against application server that runs your XML-RPC endpoint. It turns out that by default ws-xmlrpc library supports Content-Encoding HTTP header. When it observes Content-Encoding: gzip header in request, it decompress request body before process it. When we add Content-Encoding: gzip header, but body is not gzipped, we have error “Not in GZIP format”.

This leads to old but gold  ‘decompression bomb’ attack. If the attacker creates a large file that consists of ‘zeroes’, he can compress it with a very good ratio. When XML-RPC endpoint starts to decompress, it wastes computational resources.

Vulnerability CVE-2016-5002 can be abused to perform SSRF attacks. XML-RPC utilizes XML, right!? And we know that Java apps are still susceptible to XXE staff, because of insecure defaults in most Java XML parsers. It turns out, that XML parser used inside ws-xmlrpc library allows to load external DTDs. But it prohibits external parameter and general entities. That is why only SSRF attacks are possible.

When we send XML with DOCTYPE declaration that loads external DTD, we can send GET request to the host of our choice on behalf of vulnerable XML-RPC endpoint.

And the last one is CVE-2016-5003. It is about untrusted deserialization in Java. Yea! It turns out that by default  ws-xmlrpc supports java.io.Serializable data types through <ex:serializable> element. We can call some method and pass serialized Java object in <ex:serializable> element. Before calling the method, ws-xmlrpc library will deserialize our object. This is craziness! 

I’ve included Apache Commons Collections 3.2.1 dependency into pom.xml of unsafe-xmlrpc  application to show RCE attack.

As takeaways from this post, if you use ws-xmlrpc library in your Java App, patch it yourself or switch to another XML-RPC library that is safe from attacks we observed here, e.g. Redstone.