Java provides a mechanism called object serialization, which allows an object to be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object. The sequence of bytes can be used to deserialize the object graph by using the type information and bytes that represent the object and its data to recreate the object in memory. Java serialization is used by applications for multiple purposes; furthermore, Java serialization is not only used explicitly in application code. It is also used behind the scenes in many known and popular protocols.
Security issues with Java deserialization have been known for years. However, interest in the issue intensified greatly in 2015, when classes that could be abused to achieve remote code execution were found in a popular library (Apache Commons Collections). These classes were used in zero-days affecting IBM WebSphere, Oracle WebLogic, and other products, and the details were disclosed publically with no previous notification to vendors. The security community focused on exploring these issues, and as a result mitigation advice was published describing various ways to protect against this kind of attack.
Understanding where and why Java serialization is used in your applications, libraries, and frameworks will greatly help you to design an architecture to prevent this kind of attack. While it is possible (although not always easy) to protect the cases in which Java serialization is explicitly used in your application code, the cases in which it is used by frameworks and libraries may require additional security controls, as we document in this paper.
In our paper, we review the basics of the Java deserialization process and explain how and why it becomes vulnerable. We will show how different Java classes – referred to as gadgets throughout the paper – can be abused by attackers during the deserialization process to compromise or attack applications and servers. We explain how attackers can leverage these gadget classes for their own purposes. We examine several remote code execution gadgets to show how these attacks chain multiple pieces of code to craft the malicious payload. We review available mitigation advice and present a new technique to bypass some of the recommended protections. Finally, we conclude by reviewing how the problem affects similar libraries, and wrap up by offering our own mitigation strategies to more effectively protect against this problem.