Join our Newsletter — 33% off our NHI Course

What do teams get wrong about PHP deserialization security?

Teams often assume the constructor controls object state, but deserialization bypasses the constructor and restores properties directly. They also underestimate how many classes contain magic methods with side effects. Another common mistake is treating serialized data as safe application state when it may come from a request, cache, or database value that can be influenced by an attacker.

Why PHP Deserialization Becomes Dangerous So Quickly

PHP object deserialization is risky because it reconstructs object state without invoking the constructor, so any class with a dangerous magic method can run code paths the caller did not intend. That makes the security boundary the serialized payload itself, not the code that later “uses” the object. Once untrusted data reaches unserialize(), the attacker may be shaping object graphs, property values, and execution flow.

The practical mistake is to treat deserialization as a data conversion step instead of a trust decision. If the payload can be influenced through a request, cache entry, session store, or database value, the application must assume the object structure may be adversarial, not merely malformed.

Where Teams Misjudge the Attack Surface

The biggest blind spot is scope. Teams often focus only on the class they expect to deserialize, then miss the wider set of autoloaded classes already present in the application and dependencies. Any class with magic methods such as __wakeup(), __destruct(), __toString(), or __call() can become relevant if it reaches a sensitive sink.

Another common error is assuming the danger ends at object injection. In practice, the first impact may be file access, network calls, dynamic includes, state corruption, privilege checks bypassed by altered properties, or a later destructor chain that turns a “read” into a write or command execution path.

That is why code review for deserialization security has to include the whole object graph, not just the immediate call site. The exploitability of the sink depends on what classes are reachable, what magic methods they expose, and which properties influence sensitive behavior after hydration.

Why “Safe Serialized State” Is a False Assumption

Teams also get tripped up by provenance. Serialized data may come from a place that looks internal, yet still be attacker-influenced through session fixation, cache poisoning, stored input, cross-environment reuse, or another deserialization round trip. The core issue is not whether the data is “serialized,” but whether it can be treated as authenticated state.

When serialized values are persisted and later reloaded, integrity and trust boundaries matter more than format. If the application cannot prove the payload was produced by trusted code and remains bound to the expected context, then deserialization should be treated as untrusted input handling, with all the usual defensive constraints that implies.

Risk and Threat Considerations

PHP deserialization flaws are attractive because they can convert a single untrusted value into broad application control, especially when the object graph contains gadget chains in common libraries or framework code. The risk grows when the payload source is indirectly influenced rather than obviously user-controlled, because teams underestimate exposure and delay containment.

Failure mechanism: An attacker supplies or modifies serialized data so that deserialization hydrates unexpected properties, triggers magic methods, and reaches a sensitive sink such as file access, code execution, authorization bypass, or data destruction.

Impact: The result can range from logic abuse and privilege escalation to remote code execution, data theft, or persistent compromise through stored payloads that are reloaded repeatedly.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

MITRE ATT&CK and OWASP API Security Top 10 address the attack and risk surface, while OWASP ASVS, NIST SP 800-53 Rev 5 and CIS Controls v8 set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
OWASP ASVS V8 — Authorization PHP deserialization bugs often lead to permission bypass or gadget-driven access abuse.
V15 — Secure Coding and Architecture Deserializer design and gadget chains are secure architecture and coding concerns.
Recommendation — Verify that post-deserialization object state cannot bypass authorization checks. Eliminate unsafe deserialization paths and redesign object handling to avoid gadget execution.
NIST SP 800-53 Rev 5 SI-10 — Information Input Validation Untrusted serialized payloads are attacker-controlled input that must be validated before processing.
SI-7 — Software, Firmware, and Information Integrity Deserialization attacks exploit integrity loss in object state and follow-on execution paths.
Recommendation — Validate and constrain serialized input before deserializing it. Protect object integrity and detect unauthorized state manipulation.
CIS Controls v8 CIS-16 — Application Software Security Unsafe deserialization is an application security weakness requiring secure design and review.
Recommendation — Assess deserialization paths and remove insecure object hydration patterns.
MITRE ATT&CK T1203 — Exploitation for Client Execution Deserialization chains can turn crafted input into execution through application logic.
T1059 — Command and Scripting Interpreter Successful gadget chains may culminate in command execution via interpreter abuse.
Recommendation — Map deserialization chains to execution paths and hunt for gadget-triggered abuse. Inspect whether deserialization reaches command execution sinks.
OWASP API Security Top 10 API8 — Security Misconfiguration Unsafe serialization handling is a frequent configuration and implementation weakness in exposed interfaces.
Recommendation — Harden exposed endpoints that accept serialized objects and reject unsafe formats.

Practitioner Guidance

What to verify: Confirm whether every unserialize() call is protected by a trust boundary you can actually defend, not just by assumptions about where the value originated. If the payload can be influenced outside the current process, treat it as hostile until proven otherwise.

Common mistake: Do not review only the intended class. Audit reachable classes, inherited behavior, and dependency gadgets, then check whether any magic method can influence file, network, process, or security-sensitive operations after hydration.

Practitioner takeaway: The decisive question is not “does the data look internal?” but “can an attacker shape the object graph or its follow-on behavior?” If the answer is yes, deserialization must be constrained, authenticated, or replaced.