Unsafe Deserialization of untrusted data
Deserialization of untrusted data (CWE-502) occurs when applications deserialize data from untrusted sources without sufficiently verifying that the resulting data will be valid and therefore the in-memory object will be safe to use. Since this vulnerability can lead to a complete compromise of a vulnerable system, it is considered to be one of the most damaging types of attacks. To make matters worse, deserialization attacks have become one of the most widespread security vulnerabilities to occur over the past few years.
Serialization is the process of converting an object in memory into a stream of bytes in order to store it into the filesystem or transfer it to another remote application. Deserialization is the reverse process that converts the serialized stream of bytes back to an object in memory. All main programming languages, such as Java and .NET, provide facilities to perform native serialization and deserialization and most are vulnerable. Deserialization vulnerabilities are not limited to language deserialization APIs but also encompass libraries that make use of other serialization formats such as XML and JSON.
How the attack works can be summarized in the following steps:
A vulnerable application accepts user-supplied serialized objects.
An attacker performs the attack by:
creating a malicious gadget chain (sequence of method calls)
serializing it into a stream of bytes using the serialization API
sending it to the application
Deserialization occurs when the vulnerable application reads the received stream of bytes and tries to construct the object.
When a malicious object gets deserialized, the gadget chain is executed and the system is compromised.
Recommended Security Controls
According to the CERT and MITRE recommendations, to be protected against Deserialization attacks, applications must:
Minimize privileges before deserializing from a privileged context.
Not invoke potentially dangerous operations during deserialization.
Additionally OWASP states the following:
Malformed data or unexpected data could be used to abuse application logic.
Malicious objects can abuse the logic of custom deserializers in order to affect code execution.
How Waratek’s Protection Works
In accordance with the CERT, MITRE and OWASP recommendations and observations, Waratek protects against deserialization attacks (CWE-502) by addressing the problem from a privilege escalation (CWE-250) and an API abuse (CWE-227) point of view.
The task of deserialization is to convert a stream of bytes into an object in memory. The runtime platform (e.g. JVM) should allow this conversion but should not allow more privileged operations that are outside of the scope of the object deserialization API. Deserialization attacks depend on invoking API methods that are considered to be privileged, such as java.lang.Runtime.exec(), in order to perform an attack. The goal of the deserialization attack is to create a gadget chain that will reach and execute these privileged platform functions and execute the payload on the system. The payload could abuse the filesystem, the operating system, or system resources.
On specific object deserialization operations (called boundaries), the Waratek agent constructs a dynamic restricted micro-compartment on the execution thread and continues the object deserialization inside it. Waratek de-escalates the privileged operations in the micro-compartment and monitors the usage of resources. If a privileged function is invoked inside the micro-compartment, the execution is terminated and the payload is not executed. The same logic applies for Denial of Service attacks, if resources are abused inside the micro-compartment, then the deserialization process will be terminated and the attack will be prevented before the system resources are exhausted. The micro-compartment is destroyed on a non-malicious object deserialization completion and privilege de-escalation is revoked on the executing thread. The Waratek protection supports popular deserialization APIs and formats that can be used across the application. Additionally, the Waratek agent is able to protect against attacks regardless of the untrusted source e.g. when the serialized data is coming from an HTTP client (such as an external web request) or data coming from another internal system (such as a message queue).
The privilege de-escalation micro-compartment offers protection against deserialization attacks without depending on white or black listing known dangerous classes used by publicly available gadget chains and exploits. This allows users to deploy new versions of their applications without having to profile their application’s new functionality and adjust the white/black lists accordingly. Waratek offers protection against Deserialization attacks via the deserial declaration in the ARMR Marshal rule. Currently, there are 2 deserial rules:
The rce() rule, that protects against Remote Code Execution (RCE) deserialization attacks
The dos() rule, that protects against Denial-of-Service (DoS) deserialization attacks
Enabling these rules sets up the privilege de-escalation runtime micro-compartmentalization framework that monitors and controls memory allocation, CPU utilization, circular dependency depths, code injection, and privilege escalation during deserialization operations.
When the deserial rule is enabled in protect mode and a deserialization attack is identified then the malicious deserialization operation is terminated and a Java exception is thrown back to the application, in accordance with the deserialization API.
The deserial rules can be safely enabled in all types of applications in order to be protected against Java and XML deserialization attacks. Note that JSON deserialization vulnerabilities are not currently supported. XML deserialization vulnerabilities can be introduced by different XML APIs and libraries. Currently, the only XML API that is supported is java.beans.XMLDecoder.
Waratek advises the rules to be enabled even if the application does not explicitly perform deserialization operations. This is because deserialization can occur anywhere in the Java stack e.g. in WebLogic, Struts, Spring, Log4j, etc.
The deserial rules do not require any configuration overall. In very rare occasions, privileges restricted by the deserialization micro-compartment might be required by the protected application. In such cases, the AllowDeserialPrivileges Waratek property must be used to fine-tune the micro-compartment to allow the given privilege.
Because of the criticality of the vulnerability as well as because users typically are unaware if there are components anywhere in their Java stack, Waratek recommends enabling both deserial rules in order to be protected against both RCE and DoS deserialization attacks.