GiveWP flaw lets attackers run code on WordPress sites

GiveWP flaw lets attackers run code on WordPress sites

Patchstack reports that GiveWP 4.16.7.1 and below lets an attacker with no account run commands on a WordPress site; version 4.16.7.2 fixes it.

GiveWP, a WordPress donation and fundraising plugin, contains a vulnerability that lets an attacker with no account on the site run commands on the server, according to an advisory article published by Patchstack on 28 August 2026. GiveWP versions 4.16.7.1 and below are affected. The vendor released version 4.16.7.2 on 27 August 2026 to fix it, and the identifier CVE-2026-82222 has been assigned to the report. Patchstack lists the plugin at 100,000 installations and rates the flaw CVSS 10.0, the top of that severity scale.

The researcher Udin Chan discovered the flaw and reported it, according to Patchstack, which says it confirmed the problem and contacted the vendor. Patchstack also says it has issued mitigation rules to protect against exploitation of this vulnerability. GiveWP is used by nonprofits and other organisations to run donation forms, connect payment gateways, manage donors and produce reports.

What makes this serious is how little an attacker needs. On versions 4.16.5.1 and below, a default installation is enough, because GiveWP ships with an active manual (Test Donation) gateway and an active offline gateway, and only one published donation form is required. No Test Mode, open user registration, debug mode or administrator action is needed. Once the chain runs, an attacker can execute an arbitrary operating system command as the user the web server runs under, and the output of that command can be read back over HTTP.

A default install stopped being sufficient in versions 4.16.6 through 4.16.7.1, but only in the sense of reachability, not because the underlying problem was fixed. Those releases make the old donation processor stop when the submitted form is a Visual Form Builder (v3) form. Patchstack notes that a single form entry lacking its form builder settings re-arms the whole chain, and that this can sit in any post status, including draft and trashed. That covers every site upgraded from an older version, any form import or restore, and any site where an administrator has turned on the Option-Based Form Editor under Settings, Advanced.

The vulnerability is built from three parts. The first is a helper that GiveWP intended as a safe way to use unserialize, which is the PHP function that turns a stored block of text back into live programming objects. If an attacker controls that text, they can plant an object of a class they choose. The helper in the file src/Helpers/Utils.php calls unserialize with the setting allowed_classes set to false, which reads as though objects are blocked. In practice PHP still creates the object, but as a placeholder type called __PHP_Incomplete_Class that keeps the original class name and every property. When that placeholder is written back into storage, PHP re-emits the same original bytes, so the payload is not neutralised, only hidden during that single read. The attack is simply postponed to a later read that happens without the guard.

The second part is a donation flow that hands attacker-controlled data to that helper. A logged-in donor can store a serialized object in the last-name field of their own user profile. When they submit a donation, the donation processing code in includes/process-donation.php builds the donor information from that account data and passes every field through the safe unserialize helper before saving the result into the wp_give_sessions table. Because the malicious data comes back from the database rather than arriving directly in the request, ordinary input validation never sees it, and the placeholder carrying the original bytes lands in the database intact.

The third part is a gadget chain, which is a sequence of methods in classes that are already loaded that ends in a dangerous function call. GiveWP ships both the TCPDF library and its own test data classes, and together they form a complete path. Destroying the injected object enters TCPDF's destructor, which calls an internal destroy method, which reaches a forwarding method in the ProviderForwarder trait that passed its arguments straight into call_user_func_array using a callable taken from the object itself. Since the list of providers is just an array property carried inside the injected object, the attacker can point it at any function, including one that runs operating system commands.

The chain also needs a logged-in user, and GiveWP provided one for free. Patchstack reports that an unauthenticated registration action, give_action=user_register, never checks the WordPress setting that controls whether visitors may register. Even on a site with registration switched off, an attacker could create an account, receive an authentication cookie and continue immediately. Version 4.16.6 added a one-time code requirement to that handler, which narrows the window rather than closing it: the code is only output by the registration shortcode template, and WordPress issues identical one-time codes to all logged-out visitors of a given site, so on any site that shows that shortcode publicly an attacker can collect one code and reuse it.

In sequence, the reported attack had four steps. First, register an account by posting to the registration action, which returns an authentication cookie regardless of the site's registration policy. Second, read a profile code from the profile page and post the serialized gadget into the account's last name field. Third, fetch a donation code and submit a donation with form id, gateway and amount but without the last name field, which makes the server write the object into the sessions table before returning an HTTP 500 error. Fourth, request any front-end page with the same cookie, at which point the server reads the poisoned session, rebuilds the object and runs the attacker's command.

GiveWP fixed the issue in 4.16.7.2, and Patchstack highlights that the fix breaks the chain in several independent places rather than at the single entry point that was reported. An earlier attempt in 4.16.6 shows why that matters: it detected the incomplete placeholder and returned the raw serialized text, which preserved the payload exactly as before. Version 4.16.7.2 returns a failure value instead. The release then closes five points: the donation processing code rejects a donation outright if any name field holds serialized data, and a fallback user data path is passed through a cleaning function that returns an empty string for serialized input; three places that read this data back now block object creation, including the donor wall, which was reachable by an anonymous visitor through a public shortcode with no cookie at all; the forwarding gadget now checks that the provider it resolves actually implements the expected contract; donor and billing name fields are sanitised before being stored; and a migration named SanitizeSerializedObjectPayloads walks the user, donor, donation and session data tables and replaces any nested object with an empty string. That last step matters because a site that was p

How to Protect Yourself

  1. Open your WordPress dashboard, go to Plugins, and update GiveWP to version 4.16.7.2 or newer today; if someone else looks after your site, ask them to do it now.
  2. If you installed GiveWP at some point but no longer collect donations with it, delete the plugin rather than leaving it switched off, because unused plugins are still a way into a site.
  3. After updating, reload the Plugins page and check that the version number next to GiveWP really has changed, so you know the update finished.
  4. Avoid restoring an older backup of your site's database after the update, because the new version removes harmful data that an older copy would put back.
  5. Ask your hosting provider whether it can block known attack traffic to your site while the update is arranged.
  6. Turn on automatic updates for security fixes if your site supports it, and look through your plugin list once a month for anything you no longer need.

Vulnerabilities & Fixes

Terms Explained

  • PHP The programming language that WordPress and most of its plugins are written in.
  • plugin An add-on piece of software that adds extra features to a WordPress website.
  • unserialize A PHP function that turns a stored block of text back into working pieces of a program.
  • object injection Tricking a website into creating a piece of program data chosen by an attacker rather than by the site.
  • gadget chain A series of existing steps inside software that an attacker links together to reach a harmful action.
  • remote code execution Running your own commands on someone else's computer or server from a distance.
  • CVSS A standard score from 0 to 10 that says how serious a security flaw is.
  • nonce A one-time code a website hands out to check that a request really came from its own pages.

Related AEU services