PHP Object Injection: How Serialized Data Compromises Web Apps
PHP object injection turns harmless data into executable code by tricking the server into reconstructing objects with malicious properties.

PHP object injection occurs when an application unserializes user-controlled input without validation. The attacker supplies a crafted string that recreates an object with harmful properties. When the object is destroyed or used, it executes unintended actions, potentially leading to remote code execution or data theft.
What Is PHP Object Injection?
PHP object injection is a vulnerability that allows an attacker to instantiate arbitrary objects within a PHP application. The mechanism relies on the serialization feature, which converts complex objects into a storable string format. When the application later converts that string back into an object, it restores the original state. If an attacker controls the string, they control the object’s properties and behavior. This process bypasses normal application logic because the code trusts the serialized data structure. The result can be unauthorized access, data manipulation, or remote code execution, depending on what classes are available in the application environment.
At a Glance
| Aspect | Detail |
|---|---|
| Root Cause | Unsafe handling of serialized data |
| Primary Vector | User-controlled input passed to unserialize() |
| Trigger Mechanism | Object destruction or method invocation |
| Common Impact | Remote code execution, privilege escalation |
| Mitigation | Input validation, type restrictions |
How the Exploitation Chain Works
The attack begins when an application accepts input that it later passes to the unserialize function. This function reconstructs PHP objects from a string representation. Imagine a shopping cart feature that saves user preferences as a serialized string in a cookie. The application reads this cookie and unserializes it to restore the cart state. An attacker modifies the cookie value to include a different class definition. The application reconstructs this new object. If that class has a magic method, such as __destruct, which runs when the object is destroyed, the attacker’s code executes automatically. This chain relies on finding a "gadget," a class within the application that performs dangerous actions when its methods are called.
Common Gadget Chains and Forms
Attackers look for classes that interact with the file system, network, or database. These classes serve as the entry point for the exploit. A common form involves file inclusion. If a class writes to a file upon destruction, an attacker can write a malicious script to the server. Another form involves server-side request forgery (SSRF).
If a class makes HTTP requests during its lifecycle, the attacker can force the server to probe internal networks. Understanding these chains requires knowing which classes are autoloaded and how they interact. The presence of any class that accepts user input or interacts with external resources increases the risk. You must audit the entire codebase to identify potential gadgets, not just the code handling the input.
Who Is Affected by This Vulnerability?
Any application that stores and retrieves complex state using PHP serialization is at risk. This includes legacy systems that rely on session management via serialized objects. Modern frameworks that use serialization for caching or cookie storage are also vulnerable if they fail to validate the data source. The impact depends on the application’s architecture. A simple blog might only face content manipulation.
A banking portal could suffer from complete compromise. The vulnerability affects both developers who write the serialization logic and operations teams who manage the server environment. It is a server-side issue, meaning the damage occurs on the infrastructure, not just in the user’s browser. This makes it distinct from client-side vulnerabilities like cross-site scripting.
What People Usually Get Wrong
Many developers believe that preventing direct access to the unserialize function is sufficient. This is incorrect because the function is often called indirectly through library code or framework methods. Another common mistake is assuming that only user input from forms is dangerous. Cookies, hidden form fields, and API parameters are equally risky if they contain serialized data. Some teams try to blacklist specific class names, which fails when new classes are added or when aliases are used. The correct approach is to never unserialize data that you did not create yourself. If you must unserialize, verify the structure and content before the process begins. This mindset shift from blocking bad inputs to validating good structures is critical for long-term security.
How to Reduce the Risk Effectively
The most effective defense is to avoid serialization entirely for untrusted data. Use JSON or plain text formats that do not execute code upon parsing. If serialization is unavoidable, implement strict validation. Check the length of the input and ensure it matches expected patterns. Use allowlists to verify that only expected classes are instantiated. You can also use custom unserialize handlers that reject any class not explicitly permitted.
Regular vulnerability scanning can help identify exposed serialized parameters, but it cannot replace code review. Incorporate threat modeling into your development process to identify where serialization occurs and assess the risk. Change management for security patches ensures that known issues in third-party libraries are addressed promptly. This layered approach reduces the attack surface significantly.

Beyond Basic Mitigation
Advanced protection involves monitoring for anomalous object creation. Look for unexpected class instantiations or unusual method calls in logs. This can help detect ongoing exploitation attempts. You should also review how session data is stored. If sessions use serialization, ensure the session store is secure and the session ID is protected.
Consider using encrypted cookies to prevent tampering with serialized data. While this does not stop the injection, it makes it harder for an attacker to craft valid payloads. Additionally, keep your PHP version updated, as newer versions often include stricter default behaviors for object handling. This proactive stance helps maintain security as the application evolves and dependencies change.
Key takeaways
- Unserialization of untrusted input is the primary vector for this attack.
- Magic methods like __destruct or __wakeup often trigger the exploitation chain.
- Validating input before deserialization blocks most object injection attempts.
PHP object injection turns data into executable code through unsafe deserialization. Audit all unserialization points and replace them with safe data formats.
Frequently asked questions
How do I know if my PHP application is vulnerable to object injection?
Search your codebase for the unserialize function and any library calls that trigger deserialization. Check if user input, such as cookies or POST data, reaches these functions without validation.
Can a WAF stop PHP object injection attacks?
A web application firewall can block known payload patterns, but it cannot detect custom gadget chains. It provides limited protection and should not be your only defense against this vulnerability.
Is JSON serialization safe from object injection?
JSON serialization only creates arrays and objects with primitive values. It does not restore PHP class instances or methods, making it immune to object injection by design.
Should I disable the unserialize function entirely?
Disabling unserialize breaks many applications and libraries. Instead, restrict its use to trusted internal data and validate all external inputs before deserialization.
How this guide was produced: written by the BlueTeam Insider editorial team with AI assistance, checked against the public references listed below, and reviewed when the facts change. See our editorial policy or report an error.


