Insecure Deserialization: Risks and Safe Alternatives
Serialisation turns objects into a format that can be stored or sent, and deserialisation turns that data back into objects. When an application deserialises data from an untrusted source using a native object format, an attacker can craft input that executes code as it is rebuilt.
Why native deserialisation is dangerous
Native formats like Java serialisation, PHP serialize(), Python pickle, .NET BinaryFormatter and Ruby Marshal can reconstruct arbitrary object types. During that process, special methods run automatically, such as constructors, __wakeup in PHP or __reduce__ in Python. Attackers chain existing classes in your application and its libraries, called "gadget chains," to reach dangerous operations like running commands or writing files.
Python makes the danger obvious:
import pickle
pickle.loads(untrusted_bytes) # can execute arbitrary code
Where it appears
- Session data or "remember me" cookies storing serialised objects.
- Hidden form fields or view state.
- Message queues and caches shared between services.
- File imports, such as project files or saved settings.
- APIs between internal services that later become reachable externally.
- Machine learning model files loaded with pickle-based formats.
Signs to look for
- Base64 data starting with
rO0(Java serialised objects). - Strings like
O:8:"UserData":2:{...}(PHP). - Use of
pickle,yaml.loadwithout a safe loader,BinaryFormatter, orMarshal.loadon external input.
Safer alternatives
- Use data-only formats like JSON, and map them to objects explicitly with schema validation.
- Use safe loaders:
yaml.safe_loadin Python, safe parser modes in other languages. - Sign and verify any serialised data you must send to clients, using an HMAC, and reject anything tampered. Signing does not fix deserialisation flaws if the key leaks, so prefer data-only formats.
- Restrict types with allowlists where the framework supports it, such as Java serialisation filters.
- Avoid
BinaryFormatterin .NET entirely; Microsoft has deprecated it for security reasons. - Load ML models safely, preferring formats like safetensors over pickle for untrusted models.
- Keep libraries patched, as many gadget chains depend on specific library versions.
Impact
Insecure deserialisation commonly leads to remote code execution, which is why it is typically rated critical. Even without RCE, it can allow privilege escalation by tampering with object properties, such as setting isAdmin to true.
Testing for insecure deserialisation
Testing involves identifying serialised data in requests, determining the format, and safely testing whether tampered or crafted payloads are processed. SecurityInfinity agents flag serialised data in traffic, insecure patterns in code via static analysis, and verify exploitability where safe. Start free.
Frequently asked questions
Is JSON deserialisation safe?
Plain JSON parsing is safe. Risk returns if a library uses type hints in JSON to instantiate arbitrary classes, a feature some libraries offer and should be disabled.
Does encryption prevent deserialisation attacks?
Encryption hides the data but does not guarantee integrity. Use authenticated encryption or signatures, and preferably avoid native deserialisation altogether.
Is this part of the OWASP Top 10?
Yes. It falls under Software or Data Integrity Failures in the 2025 edition.