February 12, 2025
Bug Bounty Hunting: Web Vulnerability (Insecure Deserialization)
Mastering Insecure Deserialization: Techniques, Bypasses, and Exploits

By Muhammad Abdullah Niazi
2 min read
One of the most prominent security flaws in web applications known as insecure deserialization enables attackers to execute malicious code resulting in elevated privileges and data manipulation. Untrusted data deserialization happens when proper validation is excluded while allowing attackers to include malicious payloads. In this blog, I will cover how insecure deserialization manifests in PHP and Java by showing how attackers use POP (Property Oriented Programming) chains with magic methods for remote code execution attacks.
Understanding Serialization & Deserialization
- Serialization converts data into a format for storage or transmission. While Deserialization converts stored and transmitted data into original objects.
- Provides storage solutions and supports network object transfer operations for databases. For example Java, PHP, Python and Ruby.
For Example
serialize($data): Converts PHP objects into a storable string format.unserialize($data): Restores serialized data back into a PHP object.
If an attacker can control the serialized data and it's later unserialized, they can manipulate object properties or even execute arbitrary code.
PHP magic methods (__construct(), __destruct(), __wakeup(), __sleep(), __call(), etc.) can be leveraged to execute unintended behavior. Attackers commonly exploit the __destruct() method, which runs automatically when an object is destroyed. While Property Oriented Programming (POP) chains involve chaining multiple magic methods to achieve arbitrary code execution. A typical attack flow involves:
- Identifying a deserialization entry point (
unserialize()on user-controlled input). - Finding a class with a
__wakeup(),__destruct(), or__call()method. - Leveraging class methods to escalate execution.
- Constructing a payload that triggers the POP chain.
1. PHP Serialization
class User {
public $username;
public $status;
}
$user = new User;
$user->username = 'vickie';
$user->status = 'not admin';
echo serialize($user);
Produces: O:4:"User":2:{s:8:"username";s:6:"vickie";s:6:"status";s:9:"not admin";}class User {
public $username;
public $status;
}
$user = new User;
$user->username = 'vickie';
$user->status = 'not admin';
echo serialize($user);
Produces: O:4:"User":2:{s:8:"username";s:6:"vickie";s:6:"status";s:9:"not admin";}2. Exploiting PHP Object Injection
- If authentication is based on serialized data, an attacker can modify it.
- Example: Changing
statusfromnot admintoadminin serialized string:
O:4:"User":2:{s:8:"username";s:6:"vickie";s:6:"status";s:5:"admin";}O:4:"User":2:{s:8:"username";s:6:"vickie";s:6:"status";s:5:"admin";}- If
unserialize()is used without validation, an attacker can gain admin access.
3. PHP Magic Methods & RCE
__wakeup(): Called during deserialization; can execute unintended actions.__destruct(): Called when an object is destroyed; can manipulate cleanup operations.
class Example2 {
private $hook;
function __wakeup() {
if (isset($this->hook)) eval($this->hook);
}
}
$user_data = unserialize($_COOKIE['data']);class Example2 {
private $hook;
function __wakeup() {
if (isset($this->hook)) eval($this->hook);
}
}
$user_data = unserialize($_COOKIE['data']);- Example of injecting malicious payload:
class Example2 {
private $hook = "phpinfo();";
}
print urlencode(serialize(new Example2));class Example2 {
private $hook = "phpinfo();";
}
print urlencode(serialize(new Example2));- When injected into
datacookie, the server executesphpinfo();, proving code execution.
Mitigation in PHP
- Avoid
unserialize()on untrusted data. - Use JSON instead of PHP serialization (
json_encode()/json_decode()). - Implement
__wakeup()and__sleep()to restrict object reinitialization. - Use
allow_classes=falseinunserialize()(PHP 7+).
Understanding Serialization & Deserialization in Java
Java uses ObjectOutputStream.writeObject() to serialize objects and ObjectInputStream.readObject() to deserialize them.
Java POP Chains: Like PHP, Java allows chaining classes together to achieve remote code execution (RCE). The infamous Java deserialization vulnerabilities stem from the use of readObject() methods in deserialized objects. A common attack chain uses java.io.Serializable objects that invoke dangerous methods. Tools like ysoserial generate exploits for such vulnerabilities. Example payload creation:
java -jar ysoserial.jar CommonsCollections5 "calc.exe" > payload.serjava -jar ysoserial.jar CommonsCollections5 "calc.exe" > payload.serIf an application deserializespayload.ser, it will execute calc.exe on the target machine.
Mitigation in Java
- Use whitelisting: Restrict allowed classes during deserialization.
- Disable deserialization if not needed.
- Use alternative serialization formats like JSON or XML.
Conclusion
The threat level of insecure deserialization reaches an extreme if not handled properly. Attackers take advantage of magic methods, POP chains as well as unsafe object deserialization to execute arbitrary code. Developers must follow secure coding methods that exclude unserialize() introduce class filtering and select serialized formats that are secure. Security risks should be fully comprehended by developers while constructing stable applications with protection elements.