safeUnserialize Was Never Safe

There's a special place in plugin development for function names that get things wrong in a way that becomes the whole story. GiveWP, the WordPress donation plugin with more than 100,000 active installs, shipped a helper called safeUnserialize() that, as it turns out, was neither safe nor the end of the attack chain. CVE-2026-82222 is a CVSS 10.0 unauthenticated remote code execution flaw, and per the Patchstack writeup, the winning move is a chain of three individually boring-sounding pieces: that broken "safe" unserializer, a donation-processing flow that happily stores attacker-controlled serialized objects in the site's database, and a gadget chain in the libraries GiveWP bundles that can turn those stored objects into arbitrary system commands. On versions 4.16.5.1 and earlier, all an attacker needed was a default install with one published donation form and one active payment gateway. The fix, version 4.16.7.2, landed last Thursday — after Patchstack rejected several earlier patch attempts during a month-long disclosure window, which is itself a quiet lesson that the first fix for a deserialization bug is usually a bandaid, not a fix.

The part that should make WordPress admins sit up is how the "authenticated" part of this vulnerability gets quietly dissolved. The chain technically requires an account on the target site. Except GiveWP exposes an unauthenticated registration action that doesn't respect WordPress's own user-registration setting, so a site that disabled public registration in the admin panel was still handing out accounts to strangers on request. You locked the front door; a plugin left the window unlocked, and the lock you checked was a lie. From there the play is unhurried: create an account, store a malicious serialized object in the profile, donate a crafted payload through the form, and then any front-end page request unserializes the object and runs whatever command the attacker chose. No stolen credentials, no phishing, no race condition. Just the normal plumbing of a plugin that assumed its inputs were already trustworthy because someone, somewhere, had a function named safe.

Source article image
Source image 1

So here's the operational reality for anyone running WordPress — and this applies far beyond GiveWP: configuration panels in a plugin-heavy environment describe intent, not state. "Registration disabled" in Settings is a note to self; what actually gates the endpoint is whatever code path the plugin registered, and third-party code paths are exactly where deserialization, file writes, and eval-adjacent sinks live. The patch is straightforward (update to 4.16.

Source article image
Source image 2
7.2), but the honest audit question is whether any other plugin on the box trusts a setting that a plugin can override, or calls something safe because the identifier says so. I have to wonder: when your admin panel says registration is off, do you believe it — or have you ever actually probed the endpoint it's supposed to protect?

Sources

Comments

Popular posts from this blog

AI Is Starting to Feel Less Like a Gadget and More Like Infrastructure

When Two AI Bots Finally Learned to Talk in Discord

Enterprise AI Is Quietly Becoming a Systems Integration Problem