NVD published three CRITICAL-severity, network-vector vulnerabilities affecting widely deployed WordPress plugins in the last 72 hours: CVE-2026-84434 (Gravity Forms, CVSS 9.8), CVE-2026-89274 (WP Recipe Maker, CVSS 9.1), and CVE-2026-92229 (Forminator Forms, CVSS 9.1). All three are remotely exploitable over the network, and the most severe — an arbitrary file upload in Gravity Forms — is a textbook pre-authentication path to remote code execution and full site takeover.
If you run WordPress in production — and statistically, a large share of your marketing sites, customer portals, and even some internal tooling does — assume at least one of these plugins is installed somewhere in your estate. Forminator alone claims hundreds of thousands of active installations; Gravity Forms is a commercial staple across enterprise marketing stacks. This is not a niche exposure.
Historically, critical WordPress plugin vulnerabilities with public technical details are weaponized within days. Treat this as an emergency patch cycle, and hunt for retroactive compromise on any instance that was internet-facing while running a vulnerable version.
Technical Analysis
CVE-2026-84434 — Gravity Forms Arbitrary File Upload (CVSS 9.8, Critical)
Affected product: Gravity Forms plugin for WordPress, all versions up to and including 3.1.0.4.
Vulnerable component: The upload_file function.
Root cause: A mismatch between the field validation pipeline and the file persistence pipeline. Specifically:
- Hidden file upload fields bypass extension validation. When a file upload field is hidden (e.g., via conditional logic), the validation pipeline never applies the extension allowlist to it — but the field still accepts attacker-supplied files.
- Rejected files persist anyway. When a file fails validation, the upload is conceptually "rejected" — but the persistence pipeline has already written the intact uploaded file to disk. Validation failure does not equal deletion.
The result: an unauthenticated remote attacker can submit a crafted multipart form POST to any page hosting a vulnerable Gravity Forms form, smuggle a file past extension validation, and have it land intact on the server's filesystem — typically under wp-content/uploads/gravity_forms/ or a per-form upload directory. If the attacker can upload a PHP file and reach it over HTTP (a common default condition on Apache/mod_php and many nginx+php-fpm configurations where the uploads directory is not hardened), this is immediate remote code execution as the web server user, followed by database credential theft from wp-config.php and full site takeover.
CVE-2026-89274 — WP Recipe Maker Arbitrary Shortcode Execution (CVSS 9.1, Critical)
Affected product: WP Recipe Maker plugin for WordPress (per NVD, affecting versions prior to the vendor's patched release — verify against the plugin changelog).
Vulnerability class: Arbitrary shortcode execution. WordPress shortcodes are a server-side macro engine executed by do_shortcode(). Numerous plugins and themes register shortcodes that can read files, query the database, render templates, or invoke privileged plugin functionality. An attacker who can force arbitrary shortcode evaluation can frequently chain into sensitive data disclosure (e.g., shortcodes that dump post content, user metadata, or plugin settings) and, depending on the shortcode ecosystem installed, code execution.
CVE-2026-92229 — Forminator Forms (CVSS 9.1, Critical)
Affected product: The Forminator Forms – Contact Form, Payment Form & Custom Form Builder plugin for WordPress. At time of writing, NVD's published description was truncated; the 9.1 network-vector rating on a form-builder plugin warrants the same posture as the other two: form plugins handle unauthenticated file uploads and user input by design, and critical scores in this class historically map to file upload, deserialization, or injection flaws. Monitor the NVD entry and the Wordfence/plugin vendor disclosure for the full technical writeup, and patch on the assumption of worst case.
Exploitation Status
- All three CVEs carry network attack vector, low complexity CVSS characteristics consistent with remote, low-skill exploitation.
- At the time of this writing, none of the three appear on the CISA Known Exploited Vulnerabilities (KEV) catalog — but given the truncated disclosure window (published within the last 3 days), absence from KEV reflects recency, not safety. Gravity Forms file-upload flaws are exactly the class of bug that mass-exploitation botnets and initial access brokers automate within days of technical detail availability.
- Expect PoC publication and scanner signatures imminently. Patch before that happens, and hunt retroactively.
Detection & Response
This is a technical threat. The detections below target the two highest-fidelity post-exploitation observables: (1) web server processes spawning shells or interpreters (classic webshell behavior after an arbitrary file upload), and (2) PHP files written to or requested from WordPress upload directories, which should never contain executable code in a healthy deployment.
Sigma Rules
---
title: Web Server Process Spawning Shell or Script Interpreter (Webshell Execution)
id: 4f8c2e91-7a3b-4d5e-9c16-2b7a9f3e0d41
status: experimental
description: Detects Apache, nginx, or PHP-FPM spawning command shells or script interpreters — a strong indicator of webshell execution following exploitation of arbitrary file upload flaws such as CVE-2026-84434 (Gravity Forms).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-84434
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/05/20
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|endswith:
- '/apache2'
- '/httpd'
- '/nginx'
- 'php-fpm'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/zsh'
- '/python'
- '/python3'
- '/perl'
- '/php'
- '/nc'
- '/ncat'
- '/curl'
- '/wget'
condition: selection_parent and selection_child
falsepositives:
- WordPress cron jobs invoking WP-CLI or PHP via the web server context
- Legitimate plugin update routines
level: high
---
title: PHP File Written to WordPress Uploads Directory
id: 9b1d4e72-3c6a-4f8b-a2d5-8e0c7f1a6b93
status: experimental
description: Detects creation of PHP files inside wp-content/uploads, including Gravity Forms and Forminator upload paths. Executable code has no legitimate reason to be written here; this is a primary artifact of arbitrary file upload exploitation (CVE-2026-84434, CVE-2026-92229).
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-84434
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/05/20
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: file_event
product: linux
detection:
selection:
TargetFilename|contains:
- '/wp-content/uploads/'
- '/wp-content/uploads/gravity_forms/'
- '/wp-content/uploads/forminator/'
TargetFilename|endswith:
- '.php'
- '.phtml'
- '.php5'
- '.php7'
- '.phar'
- '.pht'
falsepositives:
- Rare plugin functionality writing template files; validate source process
level: critical
---
title: HTTP Request to PHP File in WordPress Uploads Directory
id: 2c7a9f13-5e8d-4b61-9a34-6d0e2c8f5b17
status: experimental
description: Detects inbound HTTP requests for PHP/PHTML files under wp-content/uploads in web server access logs — indicating an attacker accessing an uploaded webshell after exploiting an arbitrary file upload vulnerability such as CVE-2026-84434.
references:
- https://nvd.nist.gov/vuln/detail/CVE-2026-84434
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/05/20
tags:
- attack.persistence
- attack.t1505.003
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection_uri:
c-uri|contains: '/wp-content/uploads/'
selection_ext:
c-uri|endswith:
- '.php'
- '.phtml'
- '.php5'
- '.php7'
- '.phar'
- '.pht'
condition: selection_uri and selection_ext
falsepositives:
- Highly unusual; some legacy themes serve dynamic image resizers from uploads — baseline and exclude by exact path if present
level: critical
KQL — Microsoft Sentinel
The following hunts assume web server access logs are ingested into Sentinel (via the CommonSecurityLog/CEF connector, Syslog, or an IIS/Azure App Service source). The first query hunts for attacker requests reaching PHP in uploads; the second hunts endpoint telemetry for webshell process behavior on Linux web servers monitored by Defender for Endpoint.
// Hunt 1: HTTP requests to executable PHP in WordPress uploads directories
// Tables: CommonSecurityLog (CEF/WAF) or Syslog-ingested Apache/nginx logs
union isfuzzy=true
(CommonSecurityLog
| where RequestURL contains "/wp-content/uploads/"
| where RequestURL has_any (".php", ".phtml", ".php5", ".php7", ".phar", ".pht")
| project TimeGenerated, SourceIP, RequestURL, RequestMethod, HttpUserAgent, DeviceProduct),
(Syslog
| where SyslogMessage contains "/wp-content/uploads/"
| where SyslogMessage has_any (".php", ".phtml", ".phar", ".pht")
| extend RequestLine = extract(@"(?:GET|POST|PUT)\s+([^\s]+)", 1, SyslogMessage)
| where isnotempty(RequestLine)
| project TimeGenerated, Computer, HostIP, RequestLine, SyslogMessage)
| order by TimeGenerated desc;
// Hunt 2: Web server processes spawning shells/interpreters (webshell activity)
// Requires Defender for Endpoint on Linux web servers
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName has_any ("apache2", "httpd", "nginx", "php-fpm")
| where FileName has_any ("sh", "bash", "dash", "zsh", "python", "python3", "perl", "nc", "ncat", "curl", "wget")
| where ProcessCommandLine !has_any ("wp-cron", "wp-cli") // baseline legitimate WP cron
| project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, AccountName, InitiatingProcessCommandLine
| order by TimeGenerated desc;
// Hunt 3: Unauthenticated POSTs to Gravity Forms endpoints preceding compromise
// High-volume POSTs to form endpoints from single sources may indicate exploitation attempts
CommonSecurityLog
| where TimeGenerated > ago(7d)
| where RequestMethod == "POST"
| where RequestURL has_any ("gravityforms", "gf_page", "/?gf_token", "forminator", "wprm")
| summarize Requests = count(), DistinctURLs = dcount(RequestURL) by SourceIP, bin(TimeGenerated, 1h)
| where Requests > 50
| order by Requests desc;
Velociraptor VQL — Hunt for Dropped Webshells
This artifact sweeps WordPress upload trees across web servers for executable PHP files and recently modified files inside Gravity Forms / Forminator / WP Recipe Maker upload paths. Run it as a hunt across your web tier with a lookback covering at least the last 30 days.
-- Hunt: Webshell artifacts in WordPress upload directories
-- Searches for executable PHP and recently modified files in plugin upload paths
SELECT FullPath, Size, Mtime, Ctime,
read_file(filename=FullPath, length=512) AS FileHeader
FROM glob(globs=[
'/var/www/**/wp-content/uploads/**/*.php',
'/var/www/**/wp-content/uploads/**/*.phtml',
'/var/www/**/wp-content/uploads/**/*.phar',
'/var/www/**/wp-content/uploads/**/*.pht',
'/var/www/**/wp-content/uploads/**/*.php5',
'/var/www/**/wp-content/uploads/**/*.php7',
'/srv/www/**/wp-content/uploads/**/*.php',
'/usr/share/nginx/**/wp-content/uploads/**/*.php',
'/home/**/public_html/wp-content/uploads/**/*.php'
])
WHERE NOT IsDir
ORDER BY Mtime DESC;
-- Companion: recently modified files in vulnerable plugin upload dirs (last 30 days)
SELECT FullPath, Size, Mtime
FROM glob(globs=[
'/var/www/**/wp-content/uploads/gravity_forms/**/*',
'/var/www/**/wp-content/uploads/forminator/**/*',
'/var/www/**/wp-content/uploads/**/wp-recipe-maker/**/*'
])
WHERE NOT IsDir
AND Mtime > now() - 30 * 24 * 3600
ORDER BY Mtime DESC;
Remediation & Verification Script
The following Bash script audits a WordPress host for vulnerable plugin versions (via WP-CLI where available), scans upload directories for executable PHP (webshell triage), and applies upload-directory PHP execution hardening. Run it on each WordPress host or adapt for your configuration management tooling.
#!/bin/bash
# Security Arsenal — CVE-2026-84434 / CVE-2026-89274 / CVE-2026-92229 audit & hardening
# Run on each WordPress host as root or a user with WP-CLI access.
set -u
# ===== CONFIGURE: add your WordPress document roots =====
DOCROOTS=("/var/www/html" "/var/www" "/srv/www" "/home")
REPORT="/root/wp_cve_audit_$(date +%Y%m%d_%H%M%S).log"
exec > >(tee -a "$REPORT") 2>&1
echo "=== WordPress Critical Plugin CVE Audit — $(date) ==="
# --- 1. Locate WordPress installs and enumerate plugin versions ---
for root in "${DOCROOTS[@]}"; do
find "$root" -maxdepth 4 -name "wp-config.php" 2>/dev/null | while read -r cfg; do
site_dir=$(dirname "$cfg")
echo ""
echo "[+] Found WordPress install: $site_dir"
if command -v wp >/dev/null 2>&1; then
for plugin in gravityforms wp-recipe-maker forminator; do
ver=$(wp plugin get "$plugin" --field=version --path="$site_dir" --allow-root 2>/dev/null)
if [ -n "$ver" ]; then
echo " PLUGIN: $plugin version $ver"
if [ "$plugin" = "gravityforms" ]; then
# Flag any version <= 3.1.0.4 (vulnerable per CVE-2026-84434)
if [ "$(printf '%s\n' "3.1.0.4" "$ver" | sort -V | head -1)" = "$ver" ]; then
echo " *** VULNERABLE: gravityforms $ver <= 3.1.0.4 (CVE-2026-84434) — UPDATE IMMEDIATELY ***"
fi
fi
fi
done
echo " (Verify wp-recipe-maker and forminator against vendor changelogs for CVE-2026-89274 / CVE-2026-92229 patched versions)"
else
echo " [!] WP-CLI not found — check versions manually at $site_dir/wp-content/plugins/"
fi
done
done
# --- 2. Webshell triage: find executable PHP in uploads directories ---
echo ""
echo "=== Webshell Triage: PHP files under wp-content/uploads ==="
for root in "${DOCROOTS[@]}"; do
find "$root" -type d -name "uploads" -path "*wp-content*" 2>/dev/null | while read -r up; do
hits=$(find "$up" -type f \( -name "*.php" -o -name "*.phtml" -o -name "*.phar" -o -name "*.pht" -o -name "*.php[57]" \) 2>/dev/null)
if [ -n "$hits" ]; then
echo "*** SUSPICIOUS PHP in $up ***"
echo "$hits"
echo "$hits" | while read -r f; do ls -la "$f"; done
fi
done
done
# --- 3. Recently modified files in vulnerable plugin upload paths (last 14 days) ---
echo ""
echo "=== Recently modified files in gravity_forms / forminator upload paths ==="
for root in "${DOCROOTS[@]}"; do
find "$root" -type d \( -name "gravity_forms" -o -name "forminator" \) 2>/dev/null | while read -r d; do
find "$d" -type f -mtime -14 -exec ls -la {} \; 2>/dev/null
done
done
# --- 4. Hardening: block PHP execution in uploads (Apache .htaccess) ---
echo ""
echo "=== Applying upload-directory PHP execution hardening (.htaccess) ==="
HTBLOCK='<FilesMatch "\.(php|phtml|php3|php4|php5|php7|phar|pht)$">
Require all denied
</FilesMatch>'
for root in "${DOCROOTS[@]}"; do
find "$root" -type d -name "uploads" -path "*wp-content*" 2>/dev/null | while read -r up; do
if [ ! -f "$up/.htaccess" ]; then
echo "$HTBLOCK" > "$up/.htaccess"
echo " [+] Wrote PHP-block .htaccess to $up"
else
if ! grep -qi "FilesMatch" "$up/.htaccess"; then
printf '\n%s\n' "$HTBLOCK" >> "$up/.htaccess"
echo " [+] Appended PHP-block to existing $up/.htaccess"
else
echo " [=] $up/.htaccess already contains FilesMatch rules — verify manually"
fi
fi
done
done
# NOTE for nginx hosts: .htaccess is ignored. Add a location block instead:
# location ~* ^/wp-content/uploads/.*\.(php|phtml|phar|pht)$ { deny all; }
# then reload nginx: nginx -t && systemctl reload nginx
echo ""
echo "=== Audit complete. Report: $REPORT ==="
Remediation
-
Patch immediately — this is an emergency change window.
- Gravity Forms (CVE-2026-84434): All versions up to and including 3.1.0.4 are vulnerable. Update to the current release beyond 3.1.0.4 via your Gravity Forms license/auto-updater, and verify the deployed version after update. Gravity Forms is commercial — check wp-admin → Forms → System Status and your Gravity Forms account for the security release notes.
- WP Recipe Maker (CVE-2026-89274): Update to the latest release from the WordPress.org repository or via wp-admin → Dashboard → Updates. Confirm the patched version against the plugin changelog and the Wordfence/NVD advisory before closing the ticket.
- Forminator (CVE-2026-92229): Update Forminator to the latest available version immediately. Monitor the NVD entry for the full description and the exact fixed-version boundary, then re-verify.
- Official reference: NVD — CVE-2026-84434. Cross-reference the corresponding NVD entries for CVE-2026-89274 and CVE-2026-92229 as their records are fully populated.
-
If you cannot patch within hours, mitigate:
- Disable or deactivate the vulnerable plugin until patched — a broken form is cheaper than a breached site.
- Restrict access to the affected forms/pages at the WAF or reverse proxy.
- Deploy WAF virtual-patch rules blocking multipart POSTs carrying
.php/.phtml/.phar/.phtpayloads to WordPress form endpoints (ModSecurity OWASP CRS provides a baseline; add upload-path-specific rules).
-
Harden the uploads tier (defense in depth — do this regardless):
- Deny PHP execution anywhere under
wp-content/uploads/(see script above for Apache; nginx sample included in comments). This single control neutralizes the webshell-follow-on for the entire class of file upload bugs, including CVE-2026-84434. - Enforce an extension allowlist plus server-side MIME/magic-byte verification on all upload handlers.
- Ensure
wp-config.phpis not web-readable and database credentials are least-privilege.
- Deny PHP execution anywhere under
-
Hunt retroactively. Any instance that was internet-facing while vulnerable must be treated as potentially compromised:
- Run the VQL artifact and Bash triage above with a 30-day lookback.
- Review web access logs for POSTs to Gravity Forms/Forminator endpoints followed by GETs to PHP under
uploads/— that two-step pattern is the exploitation signature. - Check for rogue admin users in WordPress, unexpected files in
wp-content/plugins/, and modifiedwp-config.php/ theme files. - If any artifact is found: isolate the host, preserve disk and logs, and initiate your IR process — webshells on shared WordPress hosting routinely become pivot points.
-
Governance follow-through:
- Inventory WordPress across the enterprise — including marketing microsites, vendor-managed properties, and forgotten staging servers, which are disproportionately breached.
- Enable auto-updates for WordPress plugins where operationally acceptable, or contractually bind your hosting/agency vendors to a 24–48 hour SLA for critical plugin CVEs.
- Subscribe to plugin-specific disclosure feeds (Wordfence, Patchstack, WPScan) so a CVSS 9.8 in your stack triggers a page, not a newsletter read.
None of these CVEs are yet on CISA KEV, so there is no federal remediation deadline — but the exploitation economics of WordPress plugin bugs mean your real deadline is the first PoC drop. Move now.
Related Resources
Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.