A critical vulnerability has been disclosed in Forminator Forms, a widely deployed WordPress plugin from WPMU DEV with more than 600,000 active installations. Tracked as CVE-2026-15748 and scored 9.8 out of 10.0 (Critical) on CVSS, the flaw allows an unauthenticated attacker to upload arbitrary PHP files through the plugin's file-upload handling, which can then be executed on the server — full remote code execution with the privileges of the web server account. The vulnerability was discovered and reported by an independent security researcher.
Let me be blunt about why this matters to your team: unauthenticated file-upload-to-RCE bugs in WordPress plugins are among the most reliably mass-exploited vulnerability classes we see in incident response. Attack surface is enormous, exploitation requires no credentials, and the typical outcome is a webshell dropper followed by SEO spam, credential harvesting, lateral movement into adjacent infrastructure, or ransomware staging. If you run WordPress with Forminator installed — or you manage hosting for clients who do — this is a patch-tonight situation, and you should simultaneously hunt for compromise, because internet-wide scanning and exploitation attempts routinely begin within hours of public disclosure for bugs of this class.
Technical Analysis
Affected Products
- Product: Forminator Forms – Contact Form, Payment Form & Custom Form Builder (WordPress plugin by WPMU DEV)
- Platform: WordPress sites running Forminator with file-upload–enabled forms exposed to unauthenticated visitors
- Install base: 600,000+ active installations per the WordPress.org plugin repository
- Vulnerability: CVE-2026-15748 — CVSS 3.x score 9.8 (Critical), consistent with an unauthenticated, network-exploitable arbitrary file upload leading to remote code execution
How the Vulnerability Works (Defender's View)
Forminator allows site owners to build forms that accept file uploads from site visitors. The plugin exposes upload handling through WordPress's AJAX endpoint (/wp-admin/admin-ajax.php) and/or REST-style routes, which are reachable without authentication by design — that's how anonymous visitors submit forms.
The defect is in the validation of uploaded files: insufficient enforcement of allowed file types and insufficient server-side verification of file content and extension means an attacker can submit a crafted upload request that causes the plugin to write a malicious PHP file (e.g., shell.php, or a polyglot with a double extension) into a web-accessible directory — typically under wp-content/uploads/. Once written, the attacker sends a simple HTTP GET to the uploaded file's URL, and the PHP interpreter executes it as the web server user (www-data, apache, or the hosting account user).
A representative attack chain:
- Attacker identifies a WordPress site with Forminator installed (trivially fingerprinted via plugin asset paths like
/wp-content/plugins/forminator/). - Attacker submits a crafted multipart POST to the Forminator upload handler via
admin-ajax.php, bypassing client-side and flawed server-side file-type checks. - The malicious PHP payload is written to a predictable or enumerable path under
wp-content/uploads/forminator/(or a similar plugin upload directory). - Attacker requests the uploaded file over HTTP; code executes.
- Post-exploitation: webshell installation,
wp-config.phptheft (database credentials), admin user creation, cron/scheduled-task persistence, and traffic to attacker C2.
Exploitation Status
At the time of writing, the vulnerability is publicly disclosed with technical details available. We have not seen confirmation of CISA KEV inclusion yet, but historical precedent for unauthenticated upload-to-RCE flaws in high-install WordPress plugins is unambiguous: weaponization and automated mass scanning typically follow within 24–72 hours of disclosure. Treat this as functionally exploited in the wild for prioritization purposes. The presence of a CVSS 9.8, unauthenticated, RCE-rated bug in a 600K-install plugin belongs at the top of your patch queue — ahead of most monthly patching work.
Detection & Response
For this threat class, the highest-fidelity detections are (1) HTTP requests attempting to execute PHP files from upload directories, and (2) the web server / PHP-FPM process spawning unexpected child processes. File-integrity hunting on the uploads tree is the fastest way to find victims after the fact.
---
title: Webshell Execution Attempt via PHP Request in WordPress Uploads Directory
id: 3f8c1a2e-7b94-4d51-9e6a-2c5f8d0b1a73
status: experimental
description: Detects HTTP requests to PHP files located in WordPress uploads directories, consistent with execution of a malicious file uploaded via CVE-2026-15748 (Forminator arbitrary PHP upload). Uploaded content in wp-content/uploads should never be directly executable PHP.
references:
- https://thehackernews.com/2026/08/forminator-wordpress-flaw-can-enable.html
- https://attack.mitre.org/techniques/T1505/003/
author: Security Arsenal
date: 2026/08/14
tags:
- attack.persistence
- attack.t1505.003
logsource:
category: webserver
detection:
selection_uri:
c-uri|contains:
- '/wp-content/uploads/'
c-uri|endswith:
- '.php'
- '.phtml'
- '.php3'
- '.php5'
- '.php7'
- '.phar'
condition: selection_uri
falsepositives:
- Rare legitimate plugins that serve PHP from upload paths (non-standard and discouraged)
level: high
---
title: PHP-FPM or Web Server Spawning Shell or Reconnaissance Commands
id: 9b2e4f71-1c38-4a67-b5d2-8e0f3a6c9152
status: experimental
description: Detects the web server or PHP-FPM worker process spawning shells, downloaders, or reconnaissance binaries — a strong post-exploitation indicator following webshell deployment via CVE-2026-15748.
references:
- https://thehackernews.com/2026/08/forminator-wordpress-flaw-can-enable.html
- https://attack.mitre.org/techniques/T1059/004/
author: Security Arsenal
date: 2026/08/14
tags:
- attack.execution
- attack.t1059.004
logsource:
category: process_creation
product: linux
detection:
selection_parent:
ParentImage|contains:
- 'php-fpm'
- 'php'
- 'apache2'
- 'httpd'
- 'nginx'
selection_child:
Image|endswith:
- '/sh'
- '/bash'
- '/dash'
- '/curl'
- '/wget'
- '/nc'
- '/ncat'
- '/python'
- '/python3'
- '/perl'
- '/base64'
condition: selection_parent and selection_child
falsepositives:
- WordPress cron or backup plugins invoking system commands (rare; investigate per-host)
- Legitimate admin scripts run under the web user
level: high
---
title: Suspicious Multipart Upload to WordPress AJAX Endpoint for Forminator
id: 6d1a8c40-2f75-4e98-a3b1-7c9d2e5f0486
status: experimental
description: Detects POST requests to admin-ajax.php referencing Forminator upload actions, the expected initial access vector for CVE-2026-15748 exploitation. Tune to alert on requests originating from known-bad or non-typical geographies, or elevated volume.
references:
- https://thehackernews.com/2026/08/forminator-wordpress-flaw-can-enable.html
- https://attack.mitre.org/techniques/T1190/
author: Security Arsenal
date: 2026/08/14
tags:
- attack.initial_access
- attack.t1190
logsource:
category: webserver
detection:
selection_endpoint:
c-uri|contains: '/wp-admin/admin-ajax.php'
selection_method:
c-method: 'POST'
selection_action:
cs-uri-query|contains:
- 'forminator'
- 'action=forminator'
condition: selection_endpoint and selection_method and selection_action
falsepositives:
- Legitimate form submissions by site visitors (expect high volume on active sites — use as enrichment/context, not a standalone alert, or threshold by source IP)
level: medium
// Hunt for webshell execution: requests to PHP files under wp-content/uploads
// Works against WAF/reverse-proxy logs ingested via CEF (CommonSecurityLog) or IIS/Apache logs
CommonSecurityLog
| where TimeGenerated > ago(14d)
| where RequestURL contains "/wp-content/uploads/"
| where RequestURL has_any (".php", ".phtml", ".php3", ".php5", ".php7", ".phar")
| summarize RequestCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
by SourceIP, RequestURL, RequestMethod, DeviceAction
| order by FirstSeen asc
;
// Correlate: POSTs to Forminator upload handler followed by GET to a new .php in uploads
CommonSecurityLog
| where TimeGenerated > ago(14d)
| where RequestURL contains "admin-ajax.php" and RequestMethod =~ "POST"
| where AdditionalExtensions has "forminator" or RequestURL has "forminator"
| summarize UploadAttempts = count(), Sources = make_set(SourceIP, 20) by TimeGenerated, DestinationHostName
| order by TimeGenerated desc
;
// Endpoint-side: web server or PHP-FPM spawning suspicious child processes (Defender for Endpoint on Linux servers)
DeviceProcessEvents
| where TimeGenerated > ago(14d)
| where InitiatingProcessFileName has_any ("php-fpm", "php", "apache2", "httpd", "nginx")
| where FileName has_any ("sh", "bash", "curl", "wget", "nc", "ncat", "python", "python3", "perl", "base64")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, AccountName, InitiatingProcessCommandLine
| order by TimeGenerated desc
-- Hunt for PHP files written into WordPress uploads directories (potential webshells from CVE-2026-15748)
-- Adjust the base path glob to your hosting layout (e.g., /var/www/*/wp-content/uploads/)
LET upload_roots = glob(glob='/var/www/*/wp-content/uploads/')
SELECT FullPath,
Size,
Mtime,
Btime,
Mode
FROM glob(globs='/var/www/**/wp-content/uploads/**/*.php',
accessor='file')
ORDER BY Mtime DESC
#!/bin/bash
# CVE-2026-15748 - Forminator Forms emergency response script
# Run on each affected WordPress host (Linux). Requires wp-cli for version check/removal.
# Usage: bash forminator_cve_2026_15748_response.sh [WP_PATH]
WP_PATH="${1:-/var/www/html}"
REPORT="forminator_triage_$(date +%Y%m%d_%H%M%S).log"
echo "=== CVE-2026-15748 Forminator Response - $(hostname) - $(date) ===" | tee "$REPORT"
# 1. Check if Forminator is installed and get the version
if command -v wp >/dev/null 2>&1; then
echo "[+] Checking Forminator version via wp-cli..." | tee -a "$REPORT"
sudo -u www-data wp --path="$WP_PATH" plugin list --format=table 2>/dev/null | grep -i forminator | tee -a "$REPORT"
else
echo "[!] wp-cli not found; checking plugin directory directly." | tee -a "$REPORT"
grep -h "Version:" "$WP_PATH/wp-content/plugins/forminator/forminator.php" 2>/dev/null | tee -a "$REPORT"
fi
# 2. EMERGENCY MITIGATION: deactivate Forminator until patched version is confirmed
echo "[+] Deactivating Forminator pending patch..." | tee -a "$REPORT"
sudo -u www-data wp --path="$WP_PATH" plugin deactivate forminator 2>/dev/null | tee -a "$REPORT"
# 3. HUNT: find PHP/executable script files inside uploads tree (webshell indicator)
echo "[+] Scanning uploads for executable script files..." | tee -a "$REPORT"
find "$WP_PATH/wp-content/uploads" -type f \( -iname '*.php' -o -iname '*.phtml' -o -iname '*.phar' -o -iname '*.php*' \) -printf '%T@ %Tc %p\n' 2>/dev/null | sort -rn | head -100 | tee -a "$REPORT"
# 4. HUNT: recently modified files across the site (last 14 days)
echo "[+] Files modified in the last 14 days under webroot..." | tee -a "$REPORT"
find "$WP_PATH" -type f -mtime -14 -name '*.php' -printf '%T@ %Tc %p\n' 2>/dev/null | sort -rn | head -100 | tee -a "$REPORT"
# 5. HUNT: unauthorized WordPress admin users
echo "[+] Enumerating administrator accounts..." | tee -a "$REPORT"
sudo -u www-data wp --path="$WP_PATH" user list --role=administrator --format=table 2>/dev/null | tee -a "$REPORT"
# 6. HARDEN: block PHP execution in uploads via .htaccess (Apache) - verify nginx equivalent separately
HTACCESS="$WP_PATH/wp-content/uploads/.htaccess"
if [ ! -f "$HTACCESS" ]; then
echo "[+] Deploying PHP execution block in uploads..." | tee -a "$REPORT"
cat > "$HTACCESS" <<'EOF'
<FilesMatch "\.(php|phtml|phar|php[0-9])$">
Require all denied
</FilesMatch>
EOF
chown --reference="$WP_PATH/wp-content/uploads" "$HTACCESS" 2>/dev/null
fi
echo "=== Triage complete. Review $REPORT, then update Forminator to the latest patched release. ===" | tee -a "$REPORT"
Remediation
Immediate (within 24 hours):
- Update Forminator Forms to the latest patched release. WPMU DEV has shipped a fix — update via WordPress Dashboard → Plugins → Installed Plugins → Forminator → Update, or via
wp plugin update forminator. Verify the installed version against the official changelog at https://wordpress.org/plugins/forminator/ and the WPMU DEV advisory before declaring the site remediated. Do not assume auto-updates ran; confirm on every site, including staging and forgotten microsites. - Inventory your exposure. Enumerate every WordPress instance you own, host, or manage — including client sites, marketing landing pages, and legacy properties. The 600,000-install base means this plugin hides in places asset inventories forget.
- If you cannot patch immediately, deactivate the plugin. A broken contact form is infinitely cheaper than a webshell.
wp plugin deactivate forminatorremoves the attack surface entirely until the update is applied.
Compromise assessment (treat as assumed breach if the site was unpatched after disclosure):
- Scan the entire
wp-content/uploads/tree for PHP/phtml/phar files (see script above). Any hit is a near-certain webshell. - Review web access logs for POSTs to
admin-ajax.phpreferencing Forminator actions followed by GETs to new.phppaths — this sequence is the exploitation signature. - Audit WordPress administrator accounts,
wp-config.phpmodification times, cron entries (crontab -lfor the web user), and scheduled posts/options tables for injected content. - If compromise is confirmed: rotate database credentials in
wp-config.php, all WordPress admin passwords, salts/keys, and any API keys stored in the database — assume the web server user read everything it had access to.
Strategic hardening (this bug class, not just this CVE):
- Deny PHP execution in uploads directories at the web server layer (the script above covers Apache via
.htaccess; for nginx, add alocation ~* /uploads/.*\.php { deny all; }block). This is a durable kill switch for the entire upload-to-RCE category. - Deploy or tune a WAF (Wordfence, Cloudflare, ModSecurity) to block PHP content types in multipart uploads to WordPress AJAX endpoints.
- Run the web stack with least privilege: isolate PHP-FPM pools per site, restrict the web user's write access outside uploads, and disable dangerous PHP functions (
exec,shell_exec,system,passthru) where application-compatible. - Enable plugin auto-updates with alerting for high-install plugins, and subscribe to WordPress plugin vulnerability feeds (Wordfence, Patchstack, WPScan) so plugin CVEs trigger your vulnerability-management SLA the day they drop.
WordPress plugin flaws with this profile — unauthenticated, file upload, RCE, massive install base — are precisely the class that turns into mass compromise campaigns. Patch first, hunt second, harden the platform so the next one lands on a dead end.
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.