On November 6, Stephen Breen of Foxglove Security (@breenmachine) published a blog post outlining vulnerabilities in components of several Java Web Application Servers (WebSphere, JBoss, and WebLogic) as well as a popular development automation framework (Jenkins).
All of these vulnerabilities follow a similar pattern. And as worrying as that is, it's only the tip of the iceberg (as Foxglove’s post articulates).
So what can you do? This blog post will provide background and information on how to defend against vulnerabilities in Java serialization introduced by Apache Commons Collections affecting common Web App Servers such as WebSphere, JBoss, and Web Logic, as well as common applications like Jenkins.
As with many other security issues, the root cause of these vulnerabilities is the unintended use of a powerful feature. In this case the feature is serialization, or the process of converting complicated objects into a representation that can more easily be stored or transmitted over the network.
For example, if you had created an organization chart object, and wanted to write that to a file or send it over the network to a graphing utility, you might use a format where each member was listed with a colon and then their manager’s name immediately after. The exact format doesn’t really matter, as long as there is enough information to allow the recipient to reconstruct or deserialize the organization chart once they receive it.
Java has features designed specifically to support this kind of activity. The java.io.Serializable interface allows any class to define a writeObject() method and a corresponding readObject() method that will convert the object to a serialized form, and then recreate (or just create) an object from that representation. Not only can you create your own methods, but many of the built in Java classes implement this interface right out of the box, which can be very helpful for developers. But, as it turns out, it can also be misused by attackers.
Discovery and Mechanics
In January 2015, Gabriel Lawrence (@gebl) and Christopher Frohoff (@frohoff) presented a talk at AppSec California 2015 where they explained the dangers of serialization in a variety of languages and frameworks. One of their examples made use of the Transformer interface found in the Apache Commons Collections library. This interface allows a developer to define how to transform one type of object into another object (class). Java has a built in class called Runtime which among other things, allows the execution of commands at the operating system level. They showed how a custom class could be created that contains an object that needs transforming, and gets “transformed” by calling an operating system command of their choosing.
If an attacker serializes this custom class and sends it to some program that accepts a Java serialized object and has the Apache Commons Collections library available, then the attacker’s command will be executed automatically during deserialization.
How Common is Apache Commons Collections?
That talk was given over 10 months ago and it appears that only a handful of people really understood the impact of this technique. It turns out that the Apache Commons Collection is included in an extremely large number of Java applications, and that a good number of these applications will accept serialized objects for one reason or another.
Breen and his coworkers at Foxglove have done the legwork in finding examples of these conditions in some very popular software and notifying the respective vendors so that the problem can be addressed. While there were only five examples listed in thier post, this is likely because it takes some time to track down these cases, not because there aren’t more out there. More examples are sure to be found in the coming months and likely for several years to come.
We should also understand that this particular method of invoking a command during deserialization relies on the Apache Commons Collections library; but given the extremely rich Java ecosystem, there are sure to be other pathways using other libraries or perhaps even the Java core language itself. Library developers are in the business of making difficult things easy and don’t always realize the potential impact of some of their features. As with anything else, with great power comes great responsibility; it applies to library developers, application developers, users who choose to deploy features, and the security professionals tasked with keeping it all safe.
If these known vulnerabilities really are just the tip of the iceberg, how do you go about defending yourself from the unknown vulnerabilities to come? Standard security principles and some targeted techniques can carry you a long way.
- Limit Access to Administrative Interfaces: The majority of vulnerabilities discovered to date (though certainly not all) are found in interfaces designed to be used by administrators rather than end users. Perhaps that is because the complexity of administrative tasks lends itself to using serialized objects, or perhaps it is just because that is where researchers have looked first. In either case, disabling or limiting access to administrative interfaces is always recommended.
- Keep Software Updated: As vendors become aware of these issues, they will release updated versions to reduce or eliminate the vulnerabilities. Upgrading or applying patches regularly will allow your organization to take advantage of these fixes.
- Serialize Only When Necessary: When designing an application, recognize the risks that come with serialization and deserialization. Using language provided serialization methods opens up the entire language as a potential attack surface. If your object is simple, consider investing the time in developing a simple format that cannot be abused by potential attackers.
Commons Collections — Specific Techniques
- Identify Current Instances of Apache Commons Collections: Foxglove points out that text searching tools such as grep or findstr can be used to locate libraries that contain the required “invokerTransformer” method. If that method does not exist on your system, you are not vulnerable to this specific attack.
- Verify that Serialized Objects Are Not Accepted: This may not be easy since even though the primary functionality of an application doesn’t use serialized objects, there may be an alternate interface that does. Java serialized objects begin with hex sequence “AC ED 00 05”. Network traffic could be searched for this string to identify locations where they are being transmitted, but this will only cover functions that are exercised while the network analysis is being performed. Web Application Firewalls and similar network monitoring devices could be configured to watch for the signature over an extended period of time or to simply block it if it is ever seen. If your system does not accept serialized objects, you are not vulnerable to serialization attacks in general.
- Drastic Measures: If you find that Apache Commons Collection is present on your system and that serialized objects are required for your use case, then defending yourself against potential attacks becomes more complex. Some applications bundle libraries with an installation even though they are no longer used, so you might be able to delete the file containing the “invokerTransformer” method without consequences — but thorough testing would be required. If that fails, you might be able to unpack the library jar file, delete the InvokerTransformer.class file, and repackage the jar. Assuming this specific method from the library is not used (it probably isn’t), then the application will run fine and this attack method will no longer work. Keep in mind that new releases of the software are likely to replace this modified version of the library, so the technique would need to be repeated until the vendor fixes the issue permanently.
- Overload ReadObject(): If you are developing your own application and there is a compelling reason to use language provided serialization, Jeff Williams (current CTO of Contrast Security, former CEO of Aspect Security) offers a method that can be used to overload the default ObjectInputStream readObject() method and provide safety checking during the deserialization process.
- Runtime Application Self Protection: In the same post, Jeff points out that their flagship product, Contrast, has the ability to monitor running Java applications for security issues and can block potential attacks. There are more considerations to deploying such a product than can be covered in this post, but we’d be remiss not to mention it a possible solution.
Although serialization attacks are not new, this particular method leverages a widely used library, so many applications are likely to be vulnerable. Network vulnerability scanners may be able to detect the vulnerability in some cases, but would require a fairly invasive test to do so. In general, human effort will be required to assess a given environment and that requires awareness.
We hope that by more fully explaining the vulnerability, we can contribute to the awareness and help businesses defend themselves against it.
Need more help?
Work with our experienced security engineers to assess your critical software for vulnerabilities like these. Contact us today to learn more.