Deserialization: How it Works and Protecting Your Apps

Admir Dizdar
Share on facebook
Share on twitter
Share on linkedin

What Is Deserialization?

Insecure deserialization vulnerabilities involve the use of unknown or untrusted data and can result in attacks such as denial of service (DoS), malicious code execution, bypassing authentication measures or other abuses of application logic.

Deserialization is the process of extracting data from files, networks or streams and rebuilding it as objects—as opposed to serialization which involves converting objects to a storable format. A serialized object may be structured as text (i.e. YAML, JSON, XML, etc). 

Both serialization and deserialization are considered safe web application processes and are commonly used. However, deserialization of user inputs is considered a security misconfiguration, and can have serious consequences.

If the deserialization process is not adequately secured, attackers can exploit it to inject a malicious serialized object into an application, where the target computer deserializes the malicious data. Attackers can use insecure deserialization as an entry point to a system, from which they can pivot to further attacks.

In this article:

Types of Insecure Deserialization

The three main types of insecure deserialization attacks are:

  • Blind deserialization—these attacks occur behind a restricted system or network protected by a firewall and benefiting from robust security management policies. The attacker exploits the Java payload or manipulates a transformer chain to enable remote code execution (RCE).
  • Asynchronous deserialization—these attacks involve storing serialized gadgets in a database. When target web applications initiate deserialization, a chain of gadgets programmed to manipulate the deserialization process is executed in a JMS broker client library. JMS libraries can be vulnerable, including Oracle OpenMQ, IBM WebSphereMQ, Apache QPID JMS, Pivotal RabbitMQ and Oracle Weblogic.
  • Deferred-execution deserialization—these attacks involve the execution of a gadget chain (or chains) into vulnerable applications after the deserialization process. A gadget chain is a sequence of return-oriented programming (ROP) gadgets ending in return-from-procedure (RET) instructions. This allows an attacker to bypass any non-executable protections like kernel-code cohesion and read-only memory protections. ROP gadgets don’t require injecting binary code, so an attacker only needs to link an executable address to the required data arguments to enable code execution. 

Deserialization Attack Examples

The following examples were shared in the OWASP project’s deserialization advisory

Deserialization Using JFrame Object

A deserialization vulnerability was discovered in Adobe BlazeDS, a Java remoting and web messaging technology, and added to the Common Vulnerabilities and Exposures database as CVE-2011-2092. It has since been patched. 

Vulnerable versions of BlazeDS allow users to specify classes and properties which BlazeDS applications should deserialize. Attackers used this capability to create a JFrame object on a target BlazeDS server, which causes the JVM to exit when a user closes it. The JFrame could be used to run other malicious code on the target server.

Reading Object from Untrusted Source

The following Java code reads an object, without validating its source or sanitizing its contents, and casts it to an object. Because the casting operation happens only after deserialization, attacks may occur during the deserialization process. 

Attackers can customize deserialization protocols—for example, by overriding the readObject() function of the Java Serializable class—to achieve remote code execution in most Java applications.

Denial of Service Attack via Deserialization Loop

The following code performs a denial-of-service (DoS) attack that leverages deserialization. The root object is crafted in such a way that its members are linked together in a loop. If the application attempts to deserialize this object, the JVM will run through a recursive compute graph which never ends, and will consume 100% of CPU resources. 

How to Protect Applications Against Insecure Deserialization

There is no single solution for protecting your web applications against every kind of insecure deserialization attack. Even if you prevent deserialization of an application according to its own logic, this will not eliminate the threat altogether, given that many other components in your application stack (such as an external library) will still use a deserialization process.  

Using a WAF

There are some web application security tools that can help protect against insecure deserialization attacks, such as a web application firewall (WAF), whitelisting and blacklisting. However, each security solution also has its disadvantages, given the requirement for significant manual intervention (such as pentesting) and complex management. 

For example, a WAF is effective in restricting HTTP traffic, but it will generate large volumes of false positives. It can be difficult and expensive to maintain a WAF throughout the lifecycle of an application. Approaches such as whitelisting and blacklisting to restrict network traffic require constant maintenance and policy updates. Blacklists can produce dangerous false negatives, while whitelists can produce time-consuming false positives. 

Avoid native formats

Another risk reduction strategy is to avoid the use of native formats for deserialization—for example, you can use data-only or language-agnostic formats to make it harder for attackers to exploit deserialization logic. The only way to ensure complete protection against insecure deserialization attacks is to reject any serialized objects from an unvetted source (or to accept only the serialized objects derived from a primitive data type).

Using RASP

Runtime application self-protection (RASP) is an important DevSecOps component and embeds security in the software. RASP can detect and block attempted exploits, including insecure deserialization. It is fixed as a server-side process in the application, it monitors application behavior to identify, prevent and mitigate attacks, with no manual intervention required.    

How to Prevent Insecure Deserialization Vulnerabilities

The deserialization of user input potentially enables severe exploits that are difficult to protect against, so you should generally avoid it unless strictly necessary. In cases that do require deserialization of data from an unknown or untrusted source, you should incorporate additional security measures to verify that the data has not been manipulated by an attacker:

  • Verify data integrity by implementing a digital signature, although this only works if checks are carried out before the deserialization process begins.
  • Avoid using generic deserialization methods where possible. Serialized data often includes private fields containing sensitive information, so it is recommended you control the exposure of various fields. You can do this by creating your own serialization method that is class-specific.
  • Focus on sanitizing inputs. It is not realistic to plug every gadget chain, given the likely complexity of the cross-library dependency structure. Your application could be vulnerable at any given time, given the potential for corruption exploits of memory, which may be publicly documented. Always focus your prevention efforts on the actual vulnerability that needs to be addressed – deserialization of user input. 

Secure your app with every build

Sign up for a FREE NeuraLegion account.
Share on facebook
Share on twitter
Share on linkedin
Related Articles

Secure your app with every build

  • Easily and quickly find & fix security bugs

  • Automate it in your build pipeline

  • No false positives

  • Scan any target: web apps & APIs