logo

Why unserialize is on every PHP security checklist

Rebuilding an object from a string can run code you never intended

Joel Clermont
Joel Clermont
2026-08-03

If I asked you to name the most dangerous function in PHP, you'd probably say eval(). I'd agree, but I'd put unserialize() as a close second, and that might surprise you because serialization looks harmless at first glance.

Unserializing a string doesn't just rebuild data, it instantiates real objects. PHP will happily trigger class autoloading and run magic methods like __wakeup() and __destruct() on whatever class the string names.

Now imagine that string comes from a user. A sneaky attacker doesn't send back the object you serialized. Instead, they send a payload naming some class already loaded in your app or its dependencies, and with some clever planning, they could chain a few calls together to do some real damage.

Security folks call this a gadget chain, and it has been a top PHP attack vector since roughly PHP 4. There are even public tools that generate these payloads automatically for popular frameworks and libraries, including Laravel.

Way back in 2015, PHP 7 shipped a way to control this behavior. You could pass an allowed_classes option to unserialize(), specifying exactly which classes are safe to rebuild.

$data = unserialize($payload, ['allowed_classes' => [Invoice::class]]);

Any other class in the payload simply doesn't get instantiated, which shuts down all of those unwanted side effects.

Now if you are primarily working in a framework like Laravel, you might think "This is interesting, but I never call unserialize()."

Your framework does it all the time though. Sessions, caches, and queued jobs all flatten PHP values into strings and rebuild them later.

So what should we do about it as Laravel developers?

In an upcoming tip, I'll show a new security feature introduced in Laravel 12, and turned on by default in Laravel 13, that gives us a way to protect our cache layer from these serialization issues.

Here to help,

Joel

P.S. Did this tip leave you thinking you should learn more about Laravel security? Our free book is a great place to start.

Toss a coin in the jar if you found this helpful.
Want a tip like this in your inbox every weekday? Sign up below 👇🏼
email
No spam. Only real-world advice.