Someone left the side gate unlocked, and the guard dog only watches the front door
CVE-2026-15748 is an unauthenticated arbitrary file upload in the Forminator Forms WordPress plugin (all versions ≤ 1.56.1, 600,000+ active installs). The flaw chains two weaknesses: the plugin's sanitizer returns nested Select field values unchanged, letting an attacker smuggle a fabricated upload record through a Select field that declares itself a File Upload field with attacker-controlled configuration. The extension blocklist uses exact-key matching, which is bypassed by pipe-alternative MIME type keys — so .php files slip past the filter while WordPress still treats them as executable PHP. The result is a webshell dropped by an unauthenticated visitor submitting a crafted form. Exploitation requires the target form to contain both a File Upload field and a Select field, a common pairing in contact and application forms.
The vendor rated this CRITICAL at 9.8, which accurately reflects the *theoretical* worst case: unauth, no interaction, full RCE. However, the vendor score ignores a significant real-world friction point — default Forminator installations deploy .htaccess rules in the upload directory that block PHP execution. Only sites using a custom upload storage root that lacks this protection are exploitable for code execution. That narrows the immediately-exploitable population below the full 600K install base. noisgate downgrades to HIGH (8.6) to reflect this default-safe posture while acknowledging the attack surface remains enormous for misconfigured or custom-hosted deployments.
4 steps from start to impact.
Identify target form with Upload + Select fields
wp-content/plugins/forminator/ assets) and locates a publicly accessible form that contains both a File Upload field and a Select field. Automated scanners like WPScan or custom Nuclei templates can fingerprint the plugin version and enumerate form field types from rendered HTML.- Target runs Forminator Forms ≤ 1.56.1
- Form contains both a File Upload field and a Select field
- Form is publicly accessible (no auth wall)
- Not all Forminator forms include both field types — simple contact forms may only have text inputs
- Some sites gate forms behind login or CAPTCHA
Forge Select field value to inject upload configuration
handle_file_upload() trusts the sanitized Select field output without re-validating field type, the forged record is accepted as a legitimate upload configuration. This gives the attacker control over upload parameters including allowed extensions.- Understanding of Forminator's internal field naming convention
- Ability to send crafted multipart POST requests
- No public PoC exists yet, so attackers must reverse-engineer the field injection from the patch diff or advisory details
- WAFs with strict parameter validation may reject malformed nested objects
Bypass extension blocklist via MIME type key manipulation
.php filter. WordPress's file handling still recognizes and serves the uploaded file as PHP. The malicious .php file — typically a webshell — is written to the upload directory.- Knowledge of the specific blocklist bypass technique (pipe-alternative MIME keys)
- Default Forminator installs include
.htaccessin the upload directory that blocks PHP execution — the file lands but cannot execute - Hardened hosting (Nginx without
.htaccessequivalent, or locked-downopen_basedir) may also prevent execution
wp-content/uploads/; YARA rules for PHP webshells; EDR detecting new PHP file creation in upload pathsExecute webshell for full server compromise
.htaccess, or Nginx without equivalent deny rules), the attacker requests the uploaded PHP file directly. The webshell executes as the web server user (www-data / apache), granting command execution on the underlying OS. From here, the attacker can exfiltrate database credentials from wp-config.php, pivot laterally, install backdoors, or deploy ransomware.- Upload directory permits PHP execution (custom upload root without
.htaccessprotection) - Web server user has sufficient OS-level permissions
- Default
.htaccessprotection blocks this step entirely on standard installs - Managed WordPress hosts (WP Engine, Kinsta, Pantheon) typically enforce execution restrictions at the platform level
- SELinux / AppArmor on hardened Linux hosts may confine the web server process
www-data spawning shell processes; network monitoring for C2 callbacks; webshell scanners (e.g., PHP Malware Finder, WordFence scanner)The supporting signals.
| In-the-wild exploitation | Not confirmed. No reports of active exploitation as of 2026-08-18. Not listed on CISA KEV. |
|---|---|
| Proof-of-concept | No public PoC. The vulnerability was reported responsibly by researcher "daroo" through the Wordfence Bug Bounty Program ($2,048 bounty). Patch diff is available, making PoC development straightforward for skilled attackers. |
| EPSS score | Not yet scored (CVE is recent, published ~2 weeks ago). Given the unauth/RCE profile and large install base, expect EPSS to climb once scored. |
| KEV status | Not listed as of 2026-08-18. |
| CVSS vector | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — Network-accessible, low complexity, no privileges, no interaction. All three CIA impacts rated High. The vector does not account for the .htaccess default mitigation. |
| Affected versions | Forminator Forms ≤ 1.56.1 (all versions). Both free and Pro editions. |
| Fixed version | 1.56.2 (released 2026-07-31) |
| Install base / exposure | 600,000+ active WordPress installations per wordpress.org. WordPress sites are internet-facing by nature, making the entire install base network-reachable. No Shodan/Censys-specific data available, but plugin fingerprinting is trivial via public asset paths. |
| Disclosure date | 2026-07-31 (coordinated disclosure with patch release) |
| Reporting researcher | daroo via Wordfence Bug Bounty Program |
noisgate verdict.
The single most decisive downgrade factor is that default Forminator installations include .htaccess rules in the upload directory that prevent PHP execution, meaning the uploaded webshell lands but cannot run on standard installs — only custom upload storage roots without this protection are exploitable for RCE. The attack surface remains massive (600K+ internet-facing installs, unauth access, no interaction), which prevents further downgrade below HIGH.
Why this verdict
- Default
.htaccessfriction: Standard Forminator installs deploy.htaccessrules blocking PHP execution in the upload directory. The file uploads successfully, but the RCE kill chain breaks at the execution step. This is the primary downgrade driver from CRITICAL to HIGH. - Form configuration prerequisite: Exploitation requires a form with both a File Upload field and a Select field. While this is a common pairing (contact forms, job applications), it is not universal — simple newsletter or feedback forms are unaffected, narrowing the exploitable subset.
- No public PoC and no confirmed exploitation: As of 2026-08-18, no public exploit code exists and no in-the-wild activity has been reported. The patch diff makes weaponization feasible for skilled attackers within days to weeks, but the current threat is potential, not active.
- Role multiplier: WordPress is canonically internet-facing web infrastructure. (a) *Low-value role:* dev/staging WordPress — compromise is contained, blast radius is host-level. (b) *Typical role:* production marketing/content site — compromise yields customer data, defacement, SEO spam, or lateral pivot into internal networks via shared hosting or VPN credentials in
wp-config.php. Blast radius is host-to-tenant. (c) *High-value role:* e-commerce sites (WooCommerce), SaaS landing pages with payment integrations, multi-site networks where a single WordPress instance hosts dozens of tenants. Blast radius is tenant-to-fleet for multi-site, and includes PCI-scoped data for e-commerce. WordPress is NOT a DC, hypervisor, or IdP, so the high-value-role floor does not mandate CRITICAL — but it firmly supports HIGH given the internet-facing exposure and data-handling role. - Unauth + no interaction + internet-facing = large reachable population: The CVSS vector (AV:N/AC:L/PR:N/UI:N) is accurate for the network access component. Every site running a vulnerable form is reachable without any prior access, which prevents downgrade below HIGH.
Why not higher?
The default .htaccess protection in Forminator's upload directory blocks PHP execution on standard installations, breaking the RCE chain at the most critical step. Without hard data showing that a majority of the 600K installs use custom upload roots, the exploitable population is a *subset* of the total install base. Additionally, no public PoC or active exploitation has been confirmed, reducing the immediate threat urgency below CRITICAL.
Why not lower?
The vulnerability is unauthenticated, requires no user interaction, targets internet-facing infrastructure with 600K+ installs, and achieves full RCE when the .htaccess protection is absent. The form configuration prerequisite (Upload + Select fields) is common enough in real deployments that it does not meaningfully narrow the attack surface below the HIGH threshold. Managed hosting and Nginx deployments without equivalent deny rules may also lack the .htaccess safeguard, expanding the vulnerable population beyond just explicitly custom-configured installs.
What to do — in priority order.
- Disable or remove File Upload fields from forms with Select fields — Eliminating the field combination prerequisite completely neutralizes the attack vector. Review all Forminator forms and remove the Upload field or the Select field where both aren't strictly required. Deploy within 30 days per noisgate mitigation SLA for HIGH.
- Restrict PHP execution in upload directories at the web server level — For Apache, verify
.htaccessinwp-content/uploads/containsphp_flag engine offor equivalent<FilesMatch>deny rule. For Nginx, addlocation ~* /uploads/.*\.php$ { deny all; }to the site config. This blocks RCE even if the file upload succeeds. Deploy within 30 days. - Deploy WAF rules blocking multipart uploads with PHP extensions to Forminator endpoints — Configure Cloudflare, ModSecurity, or Sucuri to inspect POST requests to
/wp-admin/admin-ajax.php?action=forminator_submit_form_*and block payloads containing.php,.phtml,.pharfile extensions in upload fields. This catches the exploit at the network edge. - Enable file integrity monitoring on wp-content/uploads/ — Deploy FIM (OSSEC, Wazuh, or Tripwire) to alert on new
.phpfile creation in upload directories. This provides detection-in-depth if the upload succeeds but execution is blocked.
- WordPress user role restrictions — the vulnerability is unauthenticated, so limiting WordPress admin access has zero effect on this attack path.
- CAPTCHA on forms — Forminator's CAPTCHA protects against spam, not against crafted multipart POST requests sent directly to the AJAX handler, bypassing the form UI entirely.
- PHP
disable_functions— while this can limit post-exploitation impact, it does not prevent the file upload or initial webshell execution; a skilled attacker will use functions outside the disabled list.
Crowdsourced verification payload.
Run this on each WordPress host (or via SSH across your fleet) as a user with read access to the WordPress plugins directory. Example: bash check_forminator.sh /var/www/html
#!/bin/bash
# CVE-2026-15748 - Forminator Forms Arbitrary File Upload Check
# Usage: bash check_forminator.sh <wordpress_root>
# Requires: read access to WordPress plugins directory
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
WP_ROOT="${1:-.}"
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/forminator"
MAIN_FILE="$PLUGIN_DIR/forminator.php"
if [ ! -d "$PLUGIN_DIR" ]; then
echo "UNKNOWN - Forminator plugin not found at $PLUGIN_DIR"
exit 2
fi
if [ ! -f "$MAIN_FILE" ]; then
echo "UNKNOWN - Cannot read $MAIN_FILE"
exit 2
fi
# Extract version from plugin header
VERSION=$(grep -i 'Version:' "$MAIN_FILE" | head -1 | sed 's/.*Version:[[:space:]]*//' | tr -d '[:space:]')
if [ -z "$VERSION" ]; then
echo "UNKNOWN - Could not determine Forminator version"
exit 2
fi
echo "Detected Forminator version: $VERSION"
# Compare versions - 1.56.2 is the fix
# Using sort -V for version comparison
MIN_SAFE="1.56.2"
SORTED=$(printf '%s\n%s' "$VERSION" "$MIN_SAFE" | sort -V | head -1)
if [ "$SORTED" = "$MIN_SAFE" ] || [ "$VERSION" = "$MIN_SAFE" ]; then
# Version >= 1.56.2
if [ "$VERSION" = "$MIN_SAFE" ] || [ "$SORTED" = "$MIN_SAFE" ]; then
echo "PATCHED - Forminator $VERSION >= $MIN_SAFE"
# Also check htaccess as bonus
UPLOAD_DIR="$WP_ROOT/wp-content/uploads/forminator"
if [ -d "$UPLOAD_DIR" ] && [ ! -f "$UPLOAD_DIR/.htaccess" ]; then
echo "WARNING - Upload directory exists but lacks .htaccess protection: $UPLOAD_DIR"
fi
exit 0
fi
fi
# Version < 1.56.2
echo "VULNERABLE - Forminator $VERSION < $MIN_SAFE (CVE-2026-15748)"
# Check for htaccess mitigation
UPLOAD_DIR="$WP_ROOT/wp-content/uploads/forminator"
if [ -d "$UPLOAD_DIR" ]; then
if [ -f "$UPLOAD_DIR/.htaccess" ]; then
echo "NOTE - .htaccess present in upload dir (default protection may block RCE)"
else
echo "CRITICAL - No .htaccess in upload dir - RCE is likely exploitable"
fi
fi
exit 1If you remember one thing.
wp-content/uploads/ recursively for unexpected .php files that may indicate prior compromise.Sources
- The Hacker News - Forminator WordPress Flaw Enables Unauthenticated RCE
- SecurityOnline - CVE-2026-15748 Analysis
- Patchstack - Critical Arbitrary File Upload Patched in Forminator
- Wordfence - Forminator Vulnerability Intelligence
- CyberSecurityNews - Critical WordPress Plugin Vulnerability
- WPScan - Forminator Plugin Vulnerabilities
- FIRST - EPSS Scoring System
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.