Detailed Explanation of Deserialization Vulnerabilities
I. Vulnerability Description
A deserialization vulnerability refers to a security flaw in an application where, during the processing of serialized data, due to a lack of proper validation and security controls, an attacker can craft malicious serialized data to execute arbitrary code or perform other malicious operations on the target system. This type of vulnerability is often highly critical and commonly found in language environments that support object serialization, such as Java, Python, PHP, .NET, etc.
II. Basics of Serialization and Deserialization
- Serialization: The process of converting an object's state information into a storable or transmittable form (usually a byte stream).
- Example: Converting a User object into the format
{"name":"Alice","admin":false}.
- Example: Converting a User object into the format
- Deserialization: The process of restoring serialized data back into an object.
- Example: Converting
{"name":"Bob","admin":true}back into a User object instance.
- Example: Converting
III. Causes of the Vulnerability
- Blind Trust in User Input: The application directly deserializes user-controllable data without validation.
- Class Autoloading Mechanism: Automatic instantiation of malicious classes during the deserialization process.
- Presence of Magic Methods: Specific methods are automatically invoked during deserialization in certain languages.
- PHP:
__wakeup(),__destruct() - Java:
readObject(),readResolve() - Python:
__reduce__()
- PHP:
IV. Attack Principle Analysis
Using PHP as a detailed example to illustrate the attack chain:
- Malicious Class Construction
class EvilClass {
private $command = "rm -rf /";
public function __destruct() {
system($this->command); // Automatically executed when the object is destroyed
}
}
- Serializing the Malicious Object
$evil = new EvilClass();
$serialized = serialize($evil);
// Result: O:8:"EvilClass":1:{s:16:"EvilClasscommand";s:9:"rm -rf /";}
- Attack Flow
- The attacker submits malicious serialized data to the application.
- The application processes this data using the
unserialize()function. - PHP creates an instance of EvilClass and sets the $command property.
- After the request is processed, PHP's garbage collection mechanism calls
__destruct(). - The command
system("rm -rf /")is executed.
V. Vulnerability Exploitation Scenarios
- Remote Code Execution (RCE): Controlling the server by executing system commands.
- Privilege Escalation: Modifying object properties after deserialization to gain higher privileges.
- Denial of Service: Creating circular references to exhaust memory.
- Sensitive Information Disclosure: Reading private properties through deserialization.
VI. Actual Case Demonstration
Assuming a vulnerable PHP application:
// Vulnerable code example
$user_data = $_COOKIE['user'];
$user = unserialize(base64_decode($user_data)); // Directly deserializing user input
class DatabaseConnection {
private $host;
public function __wakeup() {
$this->connect();
}
private function connect() {
// Database connection logic
}
}
An attacker can:
- Craft malicious serialized data to exploit the
__wakeup()method. - Achieve SSRF attacks by modifying the host property.
- Execute code by exploiting other magic methods.
VII. Defense Measures
-
Input Validation
- Perform integrity checks on serialized data (e.g., digital signatures).
- Use allowlists to validate the source and format of serialized data.
-
Secure Configuration
- Avoid directly deserializing user input.
- Use secure data interchange formats like JSON instead of serialization.
-
Code-Level Protection
- Restrict deserializable classes: PHP's
unserialize_callback_func. - Java Security Manager: Configure
java.security.manager. - .NET's
SerializationBinder: Restrict deserializable types.
- Restrict deserializable classes: PHP's
-
Specific Protection Code Example
// Secure deserialization implementation
class SafeUnserializer {
private static $allowed_classes = ['User', 'Config'];
public static function unserialize($data) {
// Verify data signature
if (!self::verifySignature($data)) {
throw new Exception('Data tampered');
}
// Restrict deserializable classes
ini_set('unserialize_callback_func', 'spl_autoload_call');
$obj = unserialize($data, ['allowed_classes' => self::$allowed_classes]);
return $obj;
}
}
VIII. Advanced Protection Techniques
- Runtime Monitoring: Detect anomalous deserialization operations.
- Container Security: Restrict system calls in containers like Docker.
- WAF Rules: Detect common serialization attack signatures.
- Code Audits: Regularly review the use of deserialization operations.
IX. Summary
Deserialization vulnerabilities are highly critical, and defense requires a multi-layered approach:
- Development Stage: Avoid unnecessary deserialization operations.
- Testing Stage: Conduct specialized security testing.
- Runtime Stage: Implement appropriate security controls and monitoring.
- Most Importantly: Never trust serialized data from user input.
Understanding deserialization vulnerabilities requires knowledge of the language's serialization mechanisms and object lifecycle. Defenses must combine specific language features with targeted protective measures.