Web Exploitation · Term

What is insecure deserialization?

When an application rebuilds objects from attacker-controlled serialized data, the act of deserializing can trigger code paths the attacker chooses. In many stacks this becomes remote code execution before a single line of application logic runs.

TL;DR

Insecure deserialization is what happens when an application converts attacker-controlled bytes back into objects without verifying they are safe. Because deserialization can invoke constructors, magic methods, and property setters, a crafted payload can chain existing classes (a gadget chain) into arbitrary behavior, frequently remote code execution. It affects Java (via libraries like Commons Collections), PHP (unserialize with magic methods), Python (pickle), .NET, and Ruby, and the root cause is trusting serialized input.

By Pranav Khune, Lead Pentester, SecureLayer7Updated

What insecure deserialization is

Serialization turns an object into a storable or transmittable form; deserialization rebuilds it. The danger is that rebuilding an object is not passive. Depending on the language, it can call constructors, magic methods such as PHP's __wakeup and __destruct or Java's readObject, and property setters.

If an attacker controls the serialized data, they control which of those code paths run and with what values. They rarely need to inject new code. Instead they assemble a gadget chain: a sequence of methods that already exist in the application's libraries which, when triggered in order during deserialization, produce a dangerous effect such as running a command.

The abuse and payload

Testers first spot serialized data, then build or reuse a gadget chain for the stack. Shown for defensive context:

  • Spot it: Java serialized blobs start with the bytes ac ed (base64 rO0); PHP serialized strings look like O:4:"User":...; Python pickle and .NET have their own signatures.
  • Java: a tool like ysoserial generates a payload from a known gadget chain, for example java -jar ysoserial.jar CommonsCollections5 'id', delivered where the app deserializes it.
  • PHP: craft an object whose __wakeup or __destruct reaches a sensitive sink, a classic POP (property-oriented programming) chain.
  • Python: an object whose __reduce__ returns (os.system, ('id',)) runs a command the moment pickle.loads processes it.

Because exploitation happens during parsing, it is easy to miss in a code read and is a priority target in web app penetration testing.

How to defend

The reliable fix is to stop deserializing untrusted input into rich objects:

  • Prefer a data-only format such as JSON with a strict schema, and never native serialization for data that crosses a trust boundary.
  • If native serialization is unavoidable, add integrity protection, sign the payload and verify it before deserializing, and restrict allowed classes with a strict allowlist.
  • Keep gadget-bearing libraries patched and minimal; every extra library on the classpath is another potential gadget source.
  • Isolate and monitor deserialization endpoints so an attempt is logged and contained.

Treat any serialized blob arriving from a client, cookie, or message queue as hostile.

References

  1. [1]OWASP: Deserialization Cheat Sheet(OWASP)
  2. [2]PortSwigger: Insecure deserialization(PortSwigger)
  3. [3]MITRE ATT&CK: Exploit Public-Facing Application (T1190)(MITRE)
Related terms

Common questions

Insecure deserialization, asked often

Want your serialization endpoints tested?

Test your application

Find the gadget chain before an attacker does.

Our testers hunt serialized data across cookies, tokens, and message queues, then prove impact with a working chain and a developer-ready fix.

See web app penetration testing30-min scoping call, fixed-price proposal in 48 hours.