🔒 Academy Room 13 · Hard

Insecure Deserialization & PHP Object Injection

Learn how trusting serialized user input breaks an application — hands-on, against a live target. Forge the serialized cookie behind a shopping cart to inject arbitrary PHP objects, then chain a POP gadget to read a server-side file and reach remote code execution in the CartCrate lab.

⚡ Start the Deserialization Lab How it works →
// Overview

What Is Insecure Deserialization?

Serialization turns an in-memory object into a string an application can store or send — a cookie, a cache entry, a message on a queue. Deserialization rebuilds the object from that string. Insecure deserialization is what happens when that string is attacker-controlled and the application rebuilds it blindly: instead of the harmless object the developer expected, an attacker supplies one that triggers dangerous behaviour the moment it is reconstructed.

In PHP the sink is unserialize(). When it runs on data a user can change — a cart saved in a cookie, say — the attacker can inject an object of any class the application has loaded. If one of those classes runs code in a magic method such as __wakeup() or __destruct(), rebuilding the object becomes a foothold. This is PHP object injection.

// Why It Matters

Real-World Impact

Server File Disclosure

Read files off the server

Inject an object whose magic method reads a file path you control, and the application hands back the contents of a server-side file — an app config, a secrets file, an environment dump — even when that path is blocked over HTTP. No credentials required.

Remote Code Execution

Run commands on the host

Nest objects so a destructor calls into another class's method until execution reaches a command sink. The attacker controls only object properties, yet the chain — a POP gadget — turns a serialized cookie into arbitrary command execution on the server.

// OWASP

Where Insecure Deserialization Sits in the OWASP Top 10

Deserialization flaws map to A08:2021 – Software and Data Integrity Failures in the OWASP Top 10, and were their own category, A8:2017 – Insecure Deserialization, in the previous edition. They are consistently rated high impact because a working exploit so often ends in remote code execution. The impact classes below are what make them high-severity findings.

Impact What the attacker gains Severity
Server file disclosure Read app config and secrets via object injection High
Remote code execution Run commands on the host via a POP gadget chain High
Logic & auth bypass Swap object state to skip application checks Medium
Full server compromise Pivot from code execution to the underlying host High
// The Workflow

How PhantomRed Fits Into a Deserialization Assessment

The core lesson of Room 13 is that automation and human judgment are a pipeline, not a competition. An autonomous scan maps the attack surface in minutes — the exposed paths, the open ports, the forbidden directories. But insecure deserialization is a logic bug: it only reveals itself when you decode a serialized value, reason about which classes are reachable, and forge a malicious object. That's the gap a human closes.

In the lab, you run a real PhantomRed scan against CartCrate, read the surface it maps, then take over manually to exploit the deserialization the scanner can't see:

This continues the pipeline the earlier rooms built — most recently the AI insecure-output-handling lab in Room 12. Insecure deserialization is the data-integrity half of the same story: trusting a value the client was allowed to change.

// What You'll Learn

Learning Objectives

Concepts

  • How serialization carries object state, and why deserializing user input is dangerous
  • Why a magic method such as __wakeup() or __destruct() turns object injection into code
  • How insecure deserialization maps onto the OWASP Top 10

Hands-On Skills

  • Reading a scan report to map a web app's attack surface
  • Decoding and forging a serialized cookie to inject a PHP object
  • Building a POP gadget chain from file read to remote code execution
// FAQ

Frequently Asked Questions

What is insecure deserialization?
Serialization turns an in-memory object into a string an application can store or transmit; deserialization rebuilds the object from that string. Insecure deserialization happens when the string is attacker-controlled and the application rebuilds it without validation. Instead of the harmless object the developer expected, the attacker supplies one that triggers dangerous behaviour the moment it is reconstructed.
What is PHP object injection?
PHP object injection is the concrete form insecure deserialization takes in PHP. When unserialize() runs on data a user can change — a cart saved in a cookie, for example — the attacker can inject an object of any class the application has loaded. If one of those classes runs code in a magic method such as __wakeup() or __destruct(), rebuilding the object gives the attacker a foothold. It is the first flaw you exploit in the CartCrate lab.
What is a POP gadget chain?
A POP (property-oriented programming) gadget chain strings together existing classes so their magic methods call one another and reach a dangerous sink. The attacker controls only object properties, but by nesting objects they steer one class's destructor into another class's method until execution lands on a file read or a command call. In the lab you build a chain that starts from the deserialized cookie and ends in remote code execution.
Is insecure deserialization in the OWASP Top 10?
Yes. It is part of A08:2021 — Software and Data Integrity Failures in the OWASP Top 10, and was its own category, A8:2017 — Insecure Deserialization, in the previous edition. It is consistently rated high impact because a successful exploit often leads directly to remote code execution.
Can an automated scanner detect insecure deserialization?
Scanners are excellent at mapping attack surface — open ports, exposed paths, forbidden endpoints — but insecure deserialization is a logic bug. Detecting it requires decoding a serialized value, reasoning about which classes are reachable, and forging a malicious object graph, which passive scanning does not do. PhantomRed maps the surface automatically; the human closes the gap by forging the object. That workflow is the core lesson of the room.
How do you prevent insecure deserialization?
Never deserialize attacker-controlled data with native functions like unserialize(). Use a data-only format such as JSON, sign or encrypt any serialized blob that must travel through the client so it cannot be tampered with, and validate the result against a strict allow-list of expected types. Keeping dangerous logic out of magic methods removes the gadgets an attacker would otherwise chain.
// Related

Related Rooms & Guides

// Get Started

Practice Insecure Deserialization Against a Live Target

The CartCrate lab is live and free to play. Run a real autonomous scan, then exploit the deserialization the scanner can't see — inject a PHP object, read a server file, then chain a gadget to remote code execution, end to end.

⚡ Open the Deserialization Lab Start a Free Scan →