Severity Daily

IT and AI security incidents, checked against the primary source

Tag: CWE-502

  • 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.

  • A Log4j deserialization report was deleted and its author erased. Apache says it is a known non-finding; the exploit lab is still up.

    A Log4j deserialization report was deleted and its author erased. Apache says it is a known non-finding; the exploit lab is still up.

    On August 24, 2026 a researcher posting as U-Sec opened issue #4255 on the Apache Logging Services repository, describing a way to defeat Log4j’s allowlist-based deserialization filter. By August 26 the issue had been retitled “Something wrong Happen,” its body deleted, and the thread closed. The account that filed it no longer exists; GitHub now attributes the issue to “ghost.”

    That is what changed this week, and it changed on the 26th. What did not change is the surrounding material: public reproduction labs and exploit repositories built against the report are still up, downstream vendors are fielding customer questions about it, and no CVE has been assigned. The Log4j maintainers’ position, published on the project’s own security page well before any of this, is that the filter in question was never a security boundary and that defeating it is not a vulnerability in Log4j. Both of those things are true at once, and the vulnerability record has no way to say so.

    What happened

    The reported technique concerns FilteredObjectInputStream, a utility Log4j ships in log4j-api to help applications that deserialize log event streams. The report’s claim, as reproduced in third-party write-ups and in a public lab, is that the filter’s allowlist includes java.rmi.MarshalledObject, and that a MarshalledObject carries its payload as opaque bytes the class-name filter cannot see. When the object is unwrapped, MarshalledObject.get() constructs a plain, unfiltered ObjectInputStream over those bytes. Anything the filter was meant to exclude then deserializes normally.

    As of this writing the issue page at github.com/apache/logging-log4j2/issues/4255 loads, shows the title “Something wrong Happen,” the state Closed, the author “ghost,” the label waiting-for-maintainer, and the text “No description provided.” The technical description is not retrievable from it.

    The maintainers’ view is on the record, though not on that page. The Apache Logging Services security page states the project’s position on deserialization plainly, and it is worth quoting in full because it is the primary document that governs this dispute:

    “We provide no guarantee that deserializing a stream containing classes from these projects is safe, regardless of the source of the stream.”

    “Filtering such a stream by the org.apache.logging Java package, the log4net .NET namespace, or any allowlist derived from project-owned types is not sufficient to make deserialization safe.”

    “The hardening utilities we ship are partial and not exhaustive; bypasses are treated as opportunities for further hardening, not as vulnerabilities in the project.”

    “The application performing the deserialization is responsible for ensuring that the byte stream originates from a trusted source.”

    The same page notes that Log4j does not deserialize data as part of normal operation, and that FilteredObjectInputStream exists to assist applications that choose to do so anyway.

    Reporting by Cyber Kendra and SecurityWeek, both dated August 28, attributes to Log4j maintainer Piotr Karwasz a response in the issue thread describing the submission as an independent discovery of a known security non-finding, restating that the filter “is a hardening measure and never was a trust boundary,” and saying there was “no CVE, no embargo, nothing here that needs to be kept confidential.” We could not verify those words against the issue page, because the thread’s contents are gone. The Apache security page above says the same thing in the project’s own published voice, and that is the version we rely on.

    What is independently checkable is the exploitation surface. A public Docker lab, dinosn/log4j-4255, reproduces the technique end to end against official Log4j 2.26.1 artifacts on JDK 17, verifying jar checksums against Maven Central. Its README is candid about what the attack needs: “an app that exposes an unauthenticated FOIS-based serialized-LogEvent receiver and has a usable gadget version on its classpath,” and it is explicit that the outcome is gadget-dependent—commons-collections 3.2.1 yields code execution, 3.2.2 blocks it. A second repository publishes an exploit. Elastic users have opened a public thread asking whether Elastic products are affected.

    Why it matters

    Strip out the drama and this is a records problem, and a familiar one: the vulnerability database has exactly two states for a thing, and this thing is in a third.

    The project’s position is coherent. A filter documented as partial, non-exhaustive, and explicitly not a trust boundary cannot be “bypassed” in the security sense, any more than a spam folder can be bypassed. If you deserialize untrusted bytes, you have already lost, and Log4j says so in writing. Under that reading there is no Log4j vulnerability, no affected version range, and nothing for a CVE to describe. The maintainers, who are volunteers, have said as much before—in discussion #4168 on July 1, per Cyber Kendra.

    The operator’s position is also coherent, and it is not the same position. Some applications wired FilteredObjectInputStream into a network-facing receiver precisely because it looked like a boundary, following patterns from Log4j’s own samples. For those applications, the reported technique is a live unauthenticated remote code execution path, and it does not become less live because the library documented itself out of responsibility. Nobody disputes the mechanism. Apache does not dispute it; the maintainers’ answer is that it is not theirs to own.

    Between those two coherent positions falls everything that makes vulnerability management work. There is no CVE, so no scanner rule fires. There is no affected-version range, so no SBOM query resolves. There is no advisory, so no vendor has a document to link when a customer asks. There is no fix, so no patch level tells you where you stand. And the original technical report—the document that would let an engineer decide in ten minutes whether their receiver is one of the exposed ones—has been deleted from the authoritative location and survives only in third-party reproductions and a lab someone built from it. The most reliable description of the attack is now a Docker container maintained by a stranger.

    This is the same shape as several stories this site has covered in the last week, and the pattern is worth naming. When the authoritative record is unreadable—a directive whose deadline table ships as a screenshot, a vendor advisory that contradicts its own severity, an exploited flag retracted a day after it was set—the market fills the gap with transcriptions and reconstructions, and those disagree with each other. Here the gap-filling has already produced “Log4Shell 2.0” framing in at least one write-up, which is wrong on scale by a wide margin. Log4Shell was default-on, triggered by logging a string. This needs an application to deliberately stand up a serialized-LogEvent receiver, expose it to untrusted input, and carry a vulnerable gadget library. That is a narrow, opt-in configuration. Narrow is not zero, and the honest description is neither “Log4Shell 2.0” nor “nothing here.”

    The deleted account is the part that should bother people who care about how disclosure works. Whatever prompted it, the practical result is that a researcher who reported a working technique through the front door left, and the technique stayed. Reports do not become less true when their authors withdraw. They become harder to check.

    What to do

    Do not wait for a CVE, because on the project’s stated position there will not be one.

    Search your own code and your dependencies for FilteredObjectInputStream, for ObjectInputStreamLogEventBridge, and for any service that accepts serialized LogEvent objects over a socket. If you find none—which is the likely outcome for most estates—you are done, and you can say so to whoever forwarded you the “new Log4Shell” headline.

    If you find one, treat it as an unauthenticated remote code execution exposure today. Take it off any untrusted network path, put authentication and network restriction in front of it, and check the classpath for commons-collections 3.2.1 and other well-known gadget libraries; upgrading commons-collections to 3.2.2 or later closes the specific chain the public lab uses, without closing the class of attack. The durable fix is to stop deserializing untrusted Java objects in a log path at all—move to a text or structured wire format—or, if the receiver must stay, to apply a JEP 290 ObjectInputFilter configured for your own allowlist rather than relying on Log4j’s. Apache’s security page is unambiguous that this responsibility is yours.

    If you sell software, publish a position now. Customers are already asking in public forums, and “there is no CVE” is not an answer to “does your product expose a FOIS receiver.”

    Sourcing note

    Primary sources: the Apache Logging Services security page at logging.apache.org/security.html, quoted verbatim above for the project’s deserialization position; and the live state of github.com/apache/logging-log4j2/issues/4255, which we fetched directly and which currently shows the title “Something wrong Happen,” state Closed, author “ghost,” label waiting-for-maintainer, and no description. The README of the public reproduction lab dinosn/log4j-4255 is quoted for the exploitation prerequisites and the gadget dependency.

    Could not reach: the original text of issue #4255, which has been deleted; and the GitHub API, which returned 403 to unauthenticated retrieval, so we could not enumerate the thread’s comments or their timestamps. The maintainer statements—“known security non-finding,” the trust-boundary line, and “no CVE, no embargo”—are reported by Cyber Kendra and SecurityWeek (both August 28, 2026) and are attributed to them here, not confirmed by us. The July 1 date for discussion #4168 comes from the same reporting and is unverified. We did not confirm from an Apache changelog which release removed the socket server from log4j-core, so no version claim is made about it.

    Unresolved: who deleted the issue body and why; whether the account deletion was voluntary; whether any Apache Logging release will change the allowlist; and how many real deployments expose a FOIS-based receiver, a number nobody has published and which we do not estimate.