Facebook Google Plus Twitter LinkedIn YouTube RSS Menu Search Resource - BlogResource - WebinarResource - ReportResource - Eventicons_066 icons_067icons_068icons_069icons_070

[R2] Pivotal Spring Framework HttpInvokerServiceExporter readRemoteInvocation Method Untrusted Java Deserialization



Current installations of Pivotal's Spring Framework suffer from a potential remote code execution (RCE) issue. Depending on how the library is implemented within a product, it may or may not manifest, and authentication may be required. We have confirmed that current integration in commercial vendor products are affected, so this is not academic. The following write-up is based on how one vendor implemented the Spring Framework and became vulnerable, but illustrates how many other products and vendors could be impacted as well.

What Is HttpInvokerServiceExporter?

The Spring Framework Javadoc describes HttpInvokerServiceExporter as a “Servlet-API-based HTTP request handler that exports the specified service bean as HTTP invoker service endpoint, accessible via an HTTP invoker proxy.” To the layperson, this essentially means that a client can execute specific methods exposed by the creator of the server application. This functionality is very similar to RMI. In fact, the JavaDoc further describes HttpInvokerServiceExporter in terms of RMI: “Deserializes remote invocation objects and serializes remote invocation result objects. Uses Java serialization just like RMI, but provides the same ease of setup as Caucho's HTTP-based Hessian and Burlap protocols.

This Feels Oddly Familiar…

Good, because it should. In 2011, Wouter Coekaerts achieved remote code execution by deserializing proxies through this endpoint. This was assigned CVE-2011-2894 and was fixed by Pivotal by adding a flag to RemoteInvocationSerializingExporter indicating if proxy classes can be deserialized and restricting how DefaultListableBeanFactory could be deserialized. Wouter also did a very nice write-up on this vulnerability and, in 2013, Alvaro Muñoz published a working exploit.

Still Deserializing All The Things

During recent plugin development, it led Tenable to dig around a commercial product that integrates the Spring Framework. It was found to have an HTTP interface that used HTTPInvokerServiceExporter. Not knowing much about this class, we did what any good researcher would do; throw a GET request to the interface like a champ. Oddly enough, it produced a spinner and then an error message. Checking the server log:

at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2328)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2797)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:802)
at java.io.ObjectInputStream.(ObjectInputStream.java:299)
at org.springframework.core.ConfigurableObjectInputStream.(ConfigurableObjectInputStream.java:64)
at org.springframework.remoting.rmi.CodebaseAwareObjectInputStream.(CodebaseAwareObjectInputStream.java:97)
at org.springframework.remoting.rmi.RemoteInvocationSerializingExporter.createObjectInputStream(RemoteInvocationSerializingExporter.java:123)
at org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter.readRemoteInvocation(HttpInvokerServiceExporter.java:115)
at org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter.readRemoteInvocation(HttpInvokerServiceExporter.java:96)
at org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter.handleRequest(HttpInvokerServiceExporter.java:73)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)

For those that don’t stare at Java cruft for a good part of their day, this call stack tells us that HttpInvokerServiceExporter is trying to create an ObjectInputStream. Now, the application being examined is using Spring 4.1.4 but we’ll quote directly from 'master' on GitHub (8213df817e1a0f595e6aa55fecb7a5d5777f8236) for easier copy/paste access and because the code hasn’t really changed. The following method is HttpInvokerServiceExporter’s handleRequest:

public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
{ RemoteInvocation invocation = readRemoteInvocation(request); RemoteInvocationResult result = invokeAndCreateResult(invocation, getProxy()); writeRemoteInvocationResult(request, response, result); }
catch (ClassNotFoundException ex)
{ throw new NestedServletException("Class not found during deserialization", ex); }

This function is the entry point into HttpInvokerServiceExport. From the stacktrace, we know that we need to follow the HTTP request down into the readRemoteInvocation method. Which looks like this:

protected RemoteInvocation readRemoteInvocation(HttpServletRequest request)
throws IOException, ClassNotFoundException
{ return readRemoteInvocation(request, request.getInputStream()); }
Next, we have to follow the HTTP request and its payload (that is what getInputStream() is exposing) to readRemoteInvocation():
protected RemoteInvocation readRemoteInvocation(HttpServletRequest request, InputStream is)
throws IOException, ClassNotFoundException {
ObjectInputStream ois = createObjectInputStream(decorateInputStream(request, is));
{ return doReadRemoteInvocation(ois); }
{ ois.close(); }

Notice that the HTTP request’s payload just got converted into an ObjectInputStream and passed to doReadRemoteInvocation. The $1,000 question Alex, is what does doReadRemoteInvocation do with the ObjectInputStream? Looking at more code:

protected RemoteInvocation doReadRemoteInvocation(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
Object obj = ois.readObject();
if (!(obj instanceof RemoteInvocation))
{ throw new RemoteException("Deserialized object needs to be assignable to type [" + RemoteInvocation.class.getName() + "]: " + obj); }
return (RemoteInvocation) obj;

And we find classic untrusted deserialization. But there is hope! Perhaps their ObjectInputStream uses IBM’s look ahead method. Peeking into the createObjectInputStream() function we saw in readRemotInvocation we discover that the type of ObjectInputStream created is Spring Framework’s CodeAwareObjectInputStream: https://github.com/spring-projects/spring-framework/blob/183594207fbb447e1b59262b4469f2aefbb8a3ec/spring-context/src/main/java/org/springframework/remoting/rmi/CodebaseAwareObjectInputStream.java

Does it implement the look ahead technique? Unfortunately, no it does not. #SadPanda

Is that significant? Yes, as long as the appropriate libraries are included in the product we can exploit this endpoint using an HTTP POST request with a ysoserial gadget (or other unpublished gadgets) in the payload.

About Authentication

In the product we were examining, the above leads to unauthenticated remote code execution. While Spring does offer Spring Security which would require authentication before reaching this endpoint (as noted on Stack Overflow), it does not protect an application for authenticated RCE. It also won’t protect those who chose not to use Spring Security as the product being examined did. But, that is for another advisory.

Furthermore, we couldn't find any type of warning in the Javadoc or elsewhere about the possible dangers of exposing HttpInvokerServiceExporter to client requests. Based on a lack of documentation and warning, we feel that this arbitrary deserialization of all objects it not a feature, but an oversight.


Pivotal replied to our report, saying:

A look-ahead check initially sounds worthwhile for this particular case where we only intend to deserialize an instance of the RemoteInvocation class... However, RemoteInvocation may contain any argument values in its nested arguments array, so we wouldn't be gaining anything in practice.
Our general advice applies: Do not use Java serialization for external endpoints, in particular not for unauthorized ones. HTTP invoker is not a well-kept secret (or an "oversight") but rather the typical case of how a Spring application would expose serialization endpoints to begin with... he has a point that we should make this case all across our documentation, including the javadoc. But I don't really see a CVE case here, just a documentation improvement.

Pivoltal will enhance their documentation for the 4.2.6 and 3.2.17 releases.

Disclosure Timeline

2016-04-06 - Issue discovered
2016-04-08 - Submitted to ZDI for consideration, case bainesjr0006 opened
2016-04-11 - ZDI declines offer
2016-04-13 - Tenable contacts [email protected] for vuln reporting procedure
2016-04-26 - Tenable contacts [email protected] again
2016-04-26 - Automated reply, #26222 opened
2016-04-26 - Pivotal replies, looking for best contact, will get back to us
2016-04-26 - Pivotal replies, use [email protected] for vuln reporting
2016-04-26 - Tenable sends details to [email protected]
2016-04-27 - Pivotal acks mail, passed it to Spring team
2016-05-04 - Confirms issue, working as intended, will enhance documentation for 4.2.6 / 3.2.17 releases

All information within TRA advisories is provided “as is”, without warranty of any kind, including the implied warranties of merchantability and fitness for a particular purpose, and with no guarantee of completeness, accuracy, or timeliness. Individuals and organizations are responsible for assessing the impact of any actual or potential security vulnerability.

Tenable takes product security very seriously. If you believe you have found a vulnerability in one of our products, we ask that you please work with us to quickly resolve it in order to protect customers. Tenable believes in responding quickly to such reports, maintaining communication with researchers, and providing a solution in short order.

For more details on submitting vulnerability information, please see our Vulnerability Reporting Guidelines page.

If you have questions or corrections about this advisory, please email [email protected]

Try for Free Buy Now
Tenable.io FREE FOR 30 DAYS

Enjoy full access to a modern, cloud-based vulnerability management platform that enables you to see and track all of your assets with unmatched accuracy. Sign up now.

Tenable.io BUY

Enjoy full access to a modern, cloud-based vulnerability management platform that enables you to see and track all of your assets with unmatched accuracy. Purchase your annual subscription today.

65 assets

Choose Your Subscription Option:

Buy Now
Try for Free Buy Now

Try Nessus Professional Free


Nessus® is the most comprehensive vulnerability scanner on the market today. Nessus Professional will help automate the vulnerability scanning process, save time in your compliance cycles and allow you to engage your IT team.

Buy Nessus Professional

Nessus® is the most comprehensive vulnerability scanner on the market today. Nessus Professional will help automate the vulnerability scanning process, save time in your compliance cycles and allow you to engage your IT team.

Buy a multi-year license and save. Add Advanced Support for access to phone, community and chat support 24 hours a day, 365 days a year. Full details here.

Try for Free Buy Now

Try Tenable.io Web Application Scanning


Enjoy full access to our latest web application scanning offering designed for modern applications as part of the Tenable.io platform. Safely scan your entire online portfolio for vulnerabilities with a high degree of accuracy without heavy manual effort or disruption to critical web applications. Sign up now.

Buy Tenable.io Web Application Scanning

Enjoy full access to a modern, cloud-based vulnerability management platform that enables you to see and track all of your assets with unmatched accuracy. Purchase your annual subscription today.



Buy Now

Try for Free Contact Sales

Try Tenable.io Container Security


Enjoy full access to the only container security offering integrated into a vulnerability management platform. Monitor container images for vulnerabilities, malware and policy violations. Integrate with continuous integration and continuous deployment (CI/CD) systems to support DevOps practices, strengthen security and support enterprise policy compliance.

Buy Tenable.io Container Security

Tenable.io Container Security seamlessly and securely enables DevOps processes by providing visibility into the security of container images – including vulnerabilities, malware and policy violations – through integration with the build process.

Try for Free Contact Sales

Try Tenable Lumin


Visualize and explore your Cyber Exposure, track risk reduction over time and benchmark against your peers with Tenable Lumin.

Buy Tenable Lumin

Contact a Sales Representative to see how Lumin can help you gain insight across your entire organization and manage cyber risk.