Insecure Deserialization: A Silent Killer in Modern Applications

Insecure Deserialization: A Silent Killer in Modern Applications

In the realm of cybersecurity, one vulnerability that continues to haunt developers and security professionals alike is insecure deserialization. This seemingly innocuous process, crucial for transferring data between systems, harbors a myriad of risks when implemented carelessly. We delve deep into the intricacies of insecure deserialization, uncover its potential threats. I will also demonstrate practical examples in PHP, Java, and Python.

What is serialization

Serialization is the process of converting complex data structures, such as objects and their fields, into a “flatter” format that can be sent and received as a sequential stream of bytes. Serializing data makes it much simpler to:

  • Write complex data to inter-process memory, a file, or a database
  • Send complex data, for example, over a network, between different components of an application, or in an API call

Crucially, when serializing an object, its state is also persisted. In other words, the object’s attributes are preserved, along with their assigned values.

Serialization vs deserialization

Deserialization is the process of reconstructing an object from its serialized form, typically used for transmitting data between different applications or storing objects in a persistent state. Serialized data is usually represented as a string of bytes, which can be easily transmitted over networks or stored in files.

What is Insecure Deserialization?

Insecure Deserialization occurs when data from an untrusted source is deserialized, and the application:

  • Automatically instantiates classes and executes constructors/methods
  • Does not validate the structure, type, or intent of deserialized objects
  • Relies on unsafe deserialization libraries or insecure formats

This opens the door to attacks like:

  • Remote Code Execution
  • Privilege Escalation
  • DoS (Denial of Service)
  • Access Control Bypass

Real-World Example: RCE via Java Deserialization

Case: Apache Commons Collections (2015)

A critical vulnerability was discovered in the Apache Commons Collections library that allowed attackers to execute arbitrary code via serialized Java objects.

Attackers would send a malicious serialized object to a server endpoint that used ObjectInputStream without validation. When deserialized, the object triggered a chain of method calls, ultimately running system commands.

๐Ÿงช Vulnerable Code Examples

๐Ÿ”ด Java (Insecure)
import java.io.*;

public class DeserializationExample {
    public static void main(String[] args) throws Exception {
        byte[] input = getRequestInput(); // from untrusted client
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(input));
        Object obj = ois.readObject(); // ๐Ÿ”ฅ Dangerous!
        System.out.println("Object: " + obj);
    }
}

This code accepts input from an external source and blindly deserializes it using ObjectInputStream. If the input is crafted, it can trigger unwanted behavior.

โœ… Java (Secure Approach)
import java.io.*;
import java.util.*;

public class SafeDeserialization {
    public static void main(String[] args) throws Exception {
        byte[] input = getRequestInput();
        
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(input)) {
            @Override
            protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
                // Only allow specific classes to be deserialized
                if (!desc.getName().equals("java.util.HashMap")) {
                    throw new InvalidClassException("Unauthorized deserialization attempt: " + desc.getName());
                }
                return super.resolveClass(desc);
            }
        };
        
        Object obj = ois.readObject(); // Allowed: HashMap only
        System.out.println("Safe object: " + obj);
    }
}

๐Ÿ” Fix: Limit the deserialized classes. Validate content. Use safe libraries.

๐Ÿ”ด Python (Vulnerable with pickle)
import pickle

def deserialize_user_data(data):
    obj = pickle.loads(data)  # ๐Ÿ”ฅ Highly dangerous!
    return obj

Python’s pickle can execute arbitrary code if the data is malicious.

โœ… Python (Secure alternative)
import json

def safe_deserialize(data):
    obj = json.loads(data)  # Safe for strings, dicts, lists
    return obj

Use json or other non-executable formats for serialization whenever possible.

๐Ÿ”ด .NET C# (Insecure with BinaryFormatter)

We will discuss this in detail in our next blog post. But for basics, please refer below

using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public object Deserialize(byte[] data)
{
    BinaryFormatter formatter = new BinaryFormatter();
    using MemoryStream stream = new MemoryStream(data);
    return formatter.Deserialize(stream); // ๐Ÿ”ฅ Unsafe
}
โœ… .NET C# (Fix with Json or DataContract)
using System.Text.Json;

public T DeserializeSafe<T>(string json)
{
    return JsonSerializer.Deserialize<T>(json); // โœ… Safe
}

Microsoft recommends never using BinaryFormatter and switching to safer alternatives like System.Text.Json.

๐Ÿ›ก๏ธ Defense-in-Depth: How to Prevent Insecure Deserialization

PracticeWhy It Helps
Never deserialize untrusted inputCore rule. Always sanitize external data.
Use safe formats (JSON, XML)No method calls during deserialization.
Whitelist allowed typesPrevent instantiation of dangerous classes.
Use application firewalls (WAF)Block known exploit signatures.
Apply strict input validationEnsure only expected data is processed.
Update deserialization librariesVulnerabilities in older libs are common.
Monitor logs for anomaly patternsDetect unexpected object structures.

๐Ÿงฐ Tools and Libraries That Help

  • ๐Ÿ” OWASP Dependency Check โ€“ Identify vulnerable components
  • ๐Ÿ”ง SerialKiller (Java) โ€“ Safe whitelist-based deserialization
  • ๐Ÿ” Static analysis tools (e.g., SonarQube, Fortify) โ€“ Spot deserialization issues in code
  • ๐Ÿšง WAF (Web Application Firewall) โ€“ Block serialized payload attacks

โœ… Golden Rule: Never trust serialized input from external sources. If you must deserialize, sanitize ruthlessly.

Please use for portswigger labs learning the exploits.

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *