Severity Daily

IT and AI security incidents, checked against the primary source

Tag: CVE-2026-82222

  • GiveWP patched an unauthenticated CVSS 10.0 remote code execution flaw and called it additional hardening

    GiveWP patched an unauthenticated CVSS 10.0 remote code execution flaw and called it additional hardening

    GiveWP, a donation plugin installed on more than 100,000 WordPress sites, released version 4.16.7.2 on August 27, 2026. The plugin’s own changelog describes the release in one line: “Security: Added additional hardening for serialized data handling in the donation flow.”

    The following day, Patchstack published the advisory. The thing being hardened is CVE-2026-82222, an unauthenticated PHP object injection chain that ends in operating-system command execution, scored 10.0 on CVSS v3.1. On a default installation of an affected version, the only prerequisites are a published donation form and an active payment gateway.

    What happened

    NVD published the record on August 28 at 12:16 UTC. Its description, verbatim: “Deserialization of Untrusted Data vulnerability in Liquid Web / StellarWP GiveWP allows Object Injection. This issue affects GiveWP: from n/a through 4.16.7.1.” The weakness is CWE-502. The fixed version is 4.16.7.2.

    The 10.0 is worth reading precisely, because of where it comes from. NVD carries no score of its own here; the record’s vulnStatus is Deferred, meaning NVD is not performing its own analysis. The only score attached is a secondary one submitted by [email protected], the CNA: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H. Network attack vector, low complexity, no privileges, no user interaction, scope changed, high impact across confidentiality, integrity, and availability. If you query NVD for a government-analyzed severity on this CVE, you will get nothing back, and that absence is a property of the current NVD backlog rather than a judgment about the flaw.

    The chain Patchstack documents has three parts, and it is the kind of bug that only exists because a safety measure was applied in one place and not the next.

    First, GiveWP’s safeUnserialize() helper calls PHP’s unserialize() with allowed_classes => false. That is the recommended defensive setting, and it works as documented: rather than instantiating an attacker’s class, PHP produces a __PHP_Incomplete_Class placeholder. The catch is that the placeholder is not inert. It retains the original class name and properties, and when the value is serialized again on its way into storage, it re-emits them. The dangerous string survives the safe read.

    Second, the donation flow carries the payload into the database. Patchstack’s write-up describes planting a serialized gadget in an account’s last_name user meta, then submitting a donation without the give_last parameter so that the stored value is pulled through the unsafe helper and written into the wp_give_sessions table with the payload intact.

    Third, the gadget chain is already on disk. GiveWP bundles the TCPDF library and its own Give\TestData classes; ProviderForwarder::__call() passes attacker-controlled callables to call_user_func_array(), which reaches system(). Loading any front-end page deserializes the poisoned session and fires the chain, executing commands as the web server user.

    The entry point is the part that removes the last obstacle. Patchstack describes an unauthenticated give_action=user_register action that creates a WordPress account even on sites where user registration is switched off. So the five steps are: register through the plugin’s own action, plant the gadget in the profile field, submit a donation that poisons the session table, load a page, and get a shell. Patchstack states that on versions 4.16.5.1 and below the requirements are met by a default install, because GiveWP ships manual and offline gateways enabled.

    The vulnerability was reported by Udin Chan on July 28, 2026 and disclosed publicly on August 28. Patchstack’s advisory carries no claim of observed exploitation; its language is forward-looking, calling the flaw “highly dangerous and expected to become exploited” and noting that “vulnerabilities like this one are used in mass-exploit campaigns.” That is a prediction, not an observation, and we have found no report of exploitation in the wild.

    To the vendor’s credit, the fix is not a single-point patch. Patchstack describes GiveWP breaking the chain in several places at once: rejecting serialized data at write time, enforcing allowed_classes => false at multiple read sinks, validating gadget providers before they are invoked, and running a migration that sanitizes payloads already sitting in the database. That last item matters more than it sounds. It means the vendor assumed some sites were already poisoned.

    Why it matters

    Start with the changelog, because the gap between the release note and the advisory is the operational problem here.

    “Added additional hardening for serialized data handling in the donation flow” is not false. Every word of it is accurate. It is also the sentence a site owner reads inside their WordPress dashboard when deciding whether to click update today or next month, and nothing in it distinguishes this release from routine maintenance. There is no severity, no CVE, no indication that an unauthenticated stranger can run commands on the server. The advisory containing that information landed on a security vendor’s website a day later, where the site owner is not looking.

    This is the WordPress patch-gap mechanism in miniature, and it is why plugin flaws convert to mass exploitation so reliably. The population is enormous and mostly unmanaged: 100,000 active installations of a donation plugin means charities, churches, schools, volunteer-run nonprofits, and small agencies, many with auto-updates off because a plugin update broke something once. The defenders read release notes; the attackers read Patchstack and the diff. A patch is a disclosure, and an understated changelog does not slow an attacker down by a single minute—it only slows down the person who has to decide whether to interrupt their weekend. Understatement in a release note transfers risk from the vendor’s support queue to the customer’s server.

    The technical lesson is narrower and more useful. allowed_classes => false is the canonical safe-deserialization advice for PHP, and this chain runs straight through it. The reason is that the flag makes the read safe without making the value safe: __PHP_Incomplete_Class is a faithful record of a hostile object, and any code path that re-serializes it hands the payload forward to a sink that may not be so careful. If your codebase reads with allowed_classes => false and then writes the result back to a database, a cache, or a session store, you have a laundering step, not a defense. The durable fix is to refuse serialized strings at the boundary rather than to neutralize them on the way in—which is precisely what GiveWP did on the second pass.

    Two of today’s stories are CWE-502 — this one and the disputed Log4j deserialization report. That is not a coincidence so much as a reminder: object deserialization keeps producing critical bugs because it is a feature that turns data into behavior, and every mitigation built on top of it—allowlists, class filters, safe flags—is a partial one.

    What to do

    Update GiveWP to 4.16.7.2 or later. Anything at or below 4.16.7.1 is affected, and version 4.16.7.1 itself is only three days older than the fix—it shipped on August 24 and addressed an unrelated PayPal validation issue, so a site patched last week is still exposed.

    Because the vendor shipped a sanitizing migration, treat the update as remediation and not merely as prevention: it exists because payloads may already be stored. On any site running an affected version that has been reachable from the internet, do not stop at the update. Check wp_give_sessions for session data containing serialized object markers such as O: or __PHP_Incomplete_Class. Review the users table for accounts created without your knowledge, particularly with registration disabled, and inspect the last_name user meta on any account you do not recognize. Look for web-server-user processes, new or modified PHP files under wp-content, and outbound connections from the web host. Post-exploitation as the web server user is the ordinary outcome of this class of bug, and an update does not remove a shell.

    If you run many WordPress sites for other people, this is a case for reading the vulnerability feed rather than the changelog. The information you need to prioritize this release was not in the release.

    Sourcing note

    Primary sources: the NVD record for CVE-2026-82222, fetched from the NIST API, for the description, CWE, affected range, CVSS vector and score, the score’s Secondary provenance from [email protected], and the Deferred analysis status; and the GiveWP plugin listing on WordPress.org for the current version, the 100,000+ active-installation figure, and the 4.16.7.2 changelog line quoted verbatim, dated August 27, 2026.

    Technical detail of the exploit chain—the safeUnserialize() behavior, the wp_give_sessions poisoning step, the TCPDF and Give\TestData gadget path, the unauthenticated give_action=user_register entry point, the 4.16.5.1-and-below default-install claim, the July 28 report date, and the multi-point fix—comes from Patchstack’s own advisory and accompanying write-up. This is single-source vendor research: Patchstack is the CNA that assigned the CVE, the credited researcher reported through its program, and we have not independently reproduced the chain.

    The NVD record contains no cisaExploitAdd or cisaActionDue field; this CVE is not in the KEV catalog and carries no federal deadline. We found no report of exploitation in the wild. Patchstack’s “expected to become exploited” is a forecast by the disclosing vendor and is presented as such.

    Unresolved: how many of the 100,000-plus installations run an affected version, a figure nobody publishes; and whether GiveWP will amend its changelog entry to name the CVE.