Threat Overview
CVE-2026-84434 is a critical arbitrary file-upload vulnerability in the Gravity Forms WordPress plugin. A hidden File Upload field can bypass extension validation, while rejected upload state can later reach upload_file() without equivalent re-validation. On a publicly accessible form configured with a hidden file-upload field, an unauthenticated attacker can upload files that may be executable and potentially achieve remote code execution.
References
- CVE/Wordfence assignment published September 19, 2026: https://cve.report/CVE-2026-84434
- ThreatAft, September 19, 2026: https://threataft.com/articles/gravity-forms-cve-2026-84434-unauthenticated-file-upload-rce
Impacted Systems
Gravity Forms through version 3.1.0.4 when a publicly accessible form contains a File Upload field with Visibility set to Hidden. Patched in 3.1.1. WordPress/PHP deployment is required.
Why this matters
The flaw provides an unauthenticated path to dangerous file upload on Internet-facing WordPress sites and can become code execution where uploaded files are executable by the web stack.
Exploitation Status
The vulnerability is publicly disclosed and technically exploitable. Current reporting includes a VulnCheck exploitation claim, but it is not in CISA KEV as of this run, so active exploitation is not represented as independently confirmed by CISA.
What this hunt looks for
Gravity Forms upload activity, executable PHP creation under WordPress paths, requests to uploaded PHP, web-server child processes, new outbound destinations, and persistence behavior.
Required logs
WAF or reverse-proxy data in CommonSecurityLog, Defender XDR DeviceFileEvents, DeviceProcessEvents and DeviceNetworkEvents, and Syslog where available.
First Pass – Gravity Forms Upload Requests
CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where RequestURL has_any ("/wp-admin/admin-ajax.php","/wp-json/","/wp-content/uploads/")
| where Message has_any ("gravityforms","gform","upload")
| project TimeGenerated,SourceIP,DestinationIP,RequestMethod,RequestURL,DeviceAction,Message
| order by TimeGenerated descPHP Uploads Under WordPress Content
DeviceFileEvents
| where Timestamp >= ago(30d)
| where FolderPath has_any ("wp-content","uploads")
| where FileName endswith ".php" or FileName endswith ".phtml" or FileName endswith ".phar"
| where ActionType in~ ("FileCreated","FileModified")
| project Timestamp,DeviceName,ActionType,FileName,FolderPath,SHA256,InitiatingProcessFileName,InitiatingProcessCommandLine
| order by Timestamp descWeb Server Spawning Shells
DeviceProcessEvents
| where Timestamp >= ago(30d)
| where InitiatingProcessFileName in~ ("httpd","apache2","nginx","php","php-fpm")
| where FileName in~ ("sh","bash","dash","curl","wget","python","python3","powershell.exe","cmd.exe")
| project Timestamp,DeviceName,AccountName,InitiatingProcessFileName,FileName,ProcessCommandLine,SHA256
| order by Timestamp descWeb Server Outbound Connections
DeviceNetworkEvents
| where Timestamp >= ago(30d)
| where InitiatingProcessFileName in~ ("httpd","apache2","nginx","php","php-fpm")
| project Timestamp,DeviceName,InitiatingProcessFileName,InitiatingProcessCommandLine,RemoteUrl,RemoteIP,RemotePort
| order by Timestamp descNew Destinations From Web Server Processes
let Known=DeviceNetworkEvents
| where Timestamp between (ago(30d)..ago(2d))
| where InitiatingProcessFileName in~ ("httpd","apache2","nginx","php","php-fpm")
| summarize by DeviceId,RemoteIP,RemoteUrl;
DeviceNetworkEvents
| where Timestamp >= ago(2d)
| where InitiatingProcessFileName in~ ("httpd","apache2","nginx","php","php-fpm")
| join kind=leftanti Known on DeviceId,RemoteIP,RemoteUrl
| project Timestamp,DeviceName,InitiatingProcessFileName,RemoteUrl,RemoteIP,RemotePort
| order by Timestamp descRequests to Uploaded PHP
CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where RequestURL has "wp-content/uploads"
| where RequestURL matches regex @"(?i)\.(php|phtml|phar)(\?|$)"
| project TimeGenerated,SourceIP,DestinationIP,RequestMethod,RequestURL,DeviceAction,Message
| order by TimeGenerated descWordPress File Modification Burst
DeviceFileEvents
| where Timestamp >= ago(30d)
| where FolderPath has_any ("wp-content","wp-admin","wp-includes")
| where ActionType in~ ("FileCreated","FileModified")
| summarize FileChanges=count(),Files=make_set(FileName,50) by DeviceName,bin(Timestamp,10m),InitiatingProcessFileName
| where FileChanges >= 10
| order by Timestamp descSyslog Webshell Fallback
Syslog
| where TimeGenerated >= ago(30d)
| where ProcessName in~ ("apache2","httpd","nginx","php-fpm","php")
| where SyslogMessage has_any ("POST ","wp-content/uploads",".php","curl ","wget ","bash","sh -c")
| project TimeGenerated,Computer,HostName,ProcessName,SeverityLevel,SyslogMessage
| order by TimeGenerated descDetection Notes
Highest signal is executable PHP creation under upload/content paths followed by requests or web-server execution. CommonSecurityLog fields vary by parser. The hidden upload field is a configuration prerequisite, so inventory and form configuration validation are essential.