GiveWP CVE-2026-82222 Unauthenticated WordPress Remote Code Execution

Threat Overview

CVE-2026-82222 is a maximum-severity vulnerability in the GiveWP WordPress donation plugin. Public reporting on August 28, 2026 states that GiveWP through version 4.16.7.1 is affected and that exploitation can result in arbitrary operating-system command execution on the hosting server.

Patchstack’s analysis describes a three-part chain: unsafe PHP object deserialization, a donation-processing workflow that stores attacker-controlled serialized objects, and a gadget chain in bundled libraries capable of invoking system commands. Exploitation nominally requires an authenticated WordPress account, but GiveWP exposes a give_action=user_register action that can create an account even when normal WordPress registration is disabled.

Versions 4.16.6 through 4.16.7.1 require an additional condition: a legacy donation form without formBuilderSettings. GiveWP fixed the issue in version 4.16.7.2 on August 27, 2026. No confirmed in-the-wild exploitation was reported in the reviewed sources at publication time.

References

Impacted Systems

Vendor / ProductGiveWP WordPress donation plugin
VulnerabilityCVE-2026-82222 — PHP object deserialization / gadget-chain remote command execution
Affected versionsGiveWP through 4.16.7.1
Fixed version4.16.7.2, released August 27, 2026
Installation baseMore than 100,000 WordPress installations according to public reporting
Nominal authentication prerequisiteAuthenticated WordPress account
Registration bypass conditiongive_action=user_register can create an account even when normal registration is disabled
Extra condition for 4.16.6–4.16.7.1Legacy donation form without formBuilderSettings
Platform / deploymentSelf-hosted WordPress sites running GiveWP
Potential impactArbitrary operating-system command execution under the web/PHP server security context
Known exploitationNo confirmed in-the-wild exploitation reported in the reviewed sources at publication time

Why this matters

WordPress plugins are common Internet-facing attack surfaces, and GiveWP has a large deployment footprint. Successful exploitation can move directly from a web request into command execution on the underlying server, enabling web-shell deployment, credential theft, persistence, or lateral movement.

Exploitation Status

No confirmed malicious exploitation was reported in the reviewed sources as of August 29, 2026. Public technical details are sufficient to make near-term exploitation plausible, so patching and exposure validation are urgent.

What this hunt looks for

GiveWP registration and donation endpoints, bursts of new account-registration requests, server errors around donation processing, PHP/Apache/Nginx spawning shells or download utilities, suspicious files written into web roots or temporary directories, and new outbound connections from web-server processes.

Required logs

  • CommonSecurityLog or equivalent WAF/reverse-proxy/web logs
  • Syslog from Apache/Nginx/PHP/WordPress hosts
  • DeviceProcessEvents
  • DeviceFileEvents
  • DeviceNetworkEvents

Hunt 1 — First-Pass: GiveWP Registration and Donation Requests

CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where RequestURL has_any ("give_action=user_register","givewp","give-form","donation")
| project TimeGenerated, SourceIP, DestinationHostName, RequestMethod, RequestURL, RequestClientApplication, DeviceAction, Message
| sort by TimeGenerated asc

Hunt 2 — Burst of GiveWP Registration Requests by Source

CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where RequestURL has "give_action=user_register"
| summarize Requests=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), UserAgents=make_set(RequestClientApplication,20), URLs=make_set(RequestURL,30) by SourceIP, DestinationHostName, bin(TimeGenerated,15m)
| where Requests >= 3
| sort by Requests desc

Hunt 3 — GiveWP Donation Requests Followed by Server Errors

CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where RequestURL has_any ("givewp","give-form","donation")
| where Message has_any (" 500 ","HTTP 500","status=500","status 500")
| project TimeGenerated, SourceIP, DestinationHostName, RequestMethod, RequestURL, RequestClientApplication, DeviceAction, Message
| sort by TimeGenerated asc

Hunt 4 — PHP or Web Server Spawning Shell / Download Utilities

DeviceProcessEvents
| where TimeGenerated >= ago(30d)
| where InitiatingProcessFileName in~ ("php.exe","php","php-fpm","apache2","httpd","nginx")
| where FileName in~ ("cmd.exe","powershell.exe","pwsh.exe","bash","sh","curl.exe","curl","wget.exe","wget","python.exe","python","perl","nc","ncat")
| project TimeGenerated, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, SHA256
| sort by TimeGenerated asc

Hunt 5 — Web Server Writing Executable or Script Files

DeviceFileEvents
| where TimeGenerated >= ago(30d)
| where InitiatingProcessFileName in~ ("php.exe","php","php-fpm","apache2","httpd","nginx")
| where FileName endswith ".php" or FileName endswith ".phtml" or FileName endswith ".sh" or FileName endswith ".ps1" or FileName endswith ".py" or FileName endswith ".exe" or FileName endswith ".dll"
| where FolderPath has_any ("wp-content","wp-admin","wp-includes","/tmp/","/var/tmp/","\Temp\")
| project TimeGenerated, DeviceName, ActionType, FileName, FolderPath, SHA256, InitiatingProcessFileName, InitiatingProcessCommandLine
| sort by TimeGenerated asc

Hunt 6 — New Public Destinations From PHP / Web Server Processes

let Baseline = DeviceNetworkEvents
| where TimeGenerated between (ago(30d) .. ago(7d))
| where InitiatingProcessFileName in~ ("php.exe","php","php-fpm","apache2","httpd","nginx")
| where RemoteIPType == "Public"
| summarize by DeviceId, RemoteIP, RemotePort;
DeviceNetworkEvents
| where TimeGenerated >= ago(7d)
| where InitiatingProcessFileName in~ ("php.exe","php","php-fpm","apache2","httpd","nginx")
| where RemoteIPType == "Public"
| join kind=leftanti Baseline on DeviceId, RemoteIP, RemotePort
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemoteUrl, RemotePort, ActionType
| sort by TimeGenerated desc

Hunt 7 — WordPress / GiveWP Indicators in Syslog

Syslog
| where TimeGenerated >= ago(30d)
| where SyslogMessage has_any ("give_action=user_register","givewp","give-form","wp_give_sessions")
| project TimeGenerated, Computer, HostIP, ProcessName, SeverityLevel, SyslogMessage
| sort by TimeGenerated asc

Hunt 8 — Process-to-Network Correlation From Web Server Shells

let Shells = DeviceProcessEvents
| where TimeGenerated >= ago(30d)
| where InitiatingProcessFileName in~ ("php.exe","php","php-fpm","apache2","httpd","nginx")
| where FileName in~ ("cmd.exe","powershell.exe","pwsh.exe","bash","sh","curl.exe","curl","wget.exe","wget","python.exe","python")
| project DeviceId, DeviceName, ProcessTime=TimeGenerated, ChildProcess=FileName, ChildCommandLine=ProcessCommandLine;
DeviceNetworkEvents
| where TimeGenerated >= ago(30d)
| join kind=inner Shells on DeviceId
| where TimeGenerated between (ProcessTime .. ProcessTime + 10m)
| project ProcessTime, TimeGenerated, DeviceName, ChildProcess, ChildCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, RemoteIP, RemoteUrl, RemotePort, ActionType
| sort by ProcessTime asc

Detection Notes

  • The presence of give_action=user_register is not proof of exploitation; it is an exposure and reconnaissance indicator.
  • Versions 4.16.6–4.16.7.1 require a legacy donation form without formBuilderSettings.
  • HTTP 500 response matching is heuristic and can overlap with normal plugin errors.
  • Web-server child-process execution and new outbound connections are higher-signal post-exploitation indicators than request-path matching alone.
  • Without WAF/reverse-proxy logs or host telemetry from the WordPress server, Sentinel may have little visibility into the exploit chain.

Leave a comment