The bouncer checks the first ID, sees it's blank, and walks away — letting everyone behind that person into the club unchecked
CVE-2026-32475 is an unauthenticated arbitrary file upload flaw in Elementor Pro ≤ 4.2.1, the most popular WordPress page builder with 10 million+ active installations powering roughly a third of all WordPress sites. The bug lives in the Forms module's File Upload field handler (modules/forms/fields/upload.php). Two code loops — validation() and process_field() — process the same uploaded files but disagree on what to do with an empty entry. The validator hits an empty first file part (UPLOAD_ERR_NO_FILE) and executes return, killing the entire check. The processor hits the same empty entry and executes continue, skipping only that entry and happily moving the attacker's PHP payload — submitted as the second file part — into /wp-content/uploads/elementor/forms/ with a .php extension. No login, no nonce, no user interaction. The file is callable via direct HTTP GET and gives the attacker a web shell.
The vendor's CRITICAL / 9.0 rating is honest and, if anything, slightly conservative. The CVSS vector encodes AC:H because the attacker must race uniqid() to recover the dropped filename, but multiple public PoCs (Boreas37, 4minx, absholi7ly on GitHub) solve this trivially with concurrent thread pools, and Wordfence confirmed 190,000+ real-world exploitation attempts within the first five days of disclosure. Patchstack scored it 9.0; Wordfence scored it 9.8. In practice, the attack complexity is closer to Low for any attacker using automated tooling. The only real prerequisite — a published form with a non-required File Upload field — is a bread-and-butter Elementor Pro feature present on a large fraction of installations. This is a legitimate CRITICAL that we nudge to 9.2 to reflect the weaponized, actively-exploited reality.
5 steps from start to impact.
Identify vulnerable Elementor Pro form
elementor-widget-form CSS class and upload field type in the rendered HTML. Automated scanners like WPScan or custom nuclei templates can fingerprint Elementor Pro versions from asset URLs (/wp-content/plugins/elementor-pro/assets/). This step is entirely passive and unauthenticated.- Target runs Elementor Pro ≤ 4.2.1
- At least one published page contains an Elementor Pro form with a File Upload field
- File Upload field is not set as required (default state)
- Not all Elementor Pro sites have forms with file upload fields — this narrows the target population
- Sites behind WAFs with WordPress-specific rulesets (Cloudflare, Sucuri, Wordfence) may block reconnaissance
Craft desynchronized multipart upload
/wp-admin/admin-ajax.php with action=elementor_pro_forms_send_form. The file field is submitted as an array: index [0] is an empty file entry (blank filename, triggering UPLOAD_ERR_NO_FILE), and index [1] is the PHP web shell payload with a .php extension. The empty first entry causes validation() to return early, bypassing the extension blocklist entirely. The PoC tools (Boreas37's stdlib Python, 4minx's exploit) automate this construction. No authentication or CSRF token is required.- Form's POST endpoint is reachable
- No WAF rule blocks the crafted multipart structure
- Managed WordPress hosts (WP Engine, Kinsta, Pantheon) often disable PHP execution in
/uploads/directories, which blocks step 4 even if the file lands - Some WAFs specifically block
.phpin upload filenames at the network layer
PHP file written to public uploads directory
process_field() loop encounters the empty first entry, executes continue, then moves the PHP payload to /wp-content/uploads/elementor/forms/<uniqid>.php. The filename is generated by PHP's uniqid() — a 13-character hex string derived from server microsecond time. The file is world-readable via direct HTTP request. At this point the attacker has achieved arbitrary file write but not yet code execution.- Web server process has write permission to uploads directory (standard WordPress)
- No filesystem-level restriction prevents .php file creation in uploads
- Hosts with
open_basediror AppArmor/SELinux profiles may restrict writes - Some security plugins (iThemes, Wordfence) monitor uploads directory for new PHP files and alert or quarantine
Recover dropped filename via uniqid sweep
uniqid()-based filename to request the shell. Public PoCs use concurrent thread pools (default 24 workers) to probe filenames across the microsecond window surrounding the upload timestamp. Boreas37's PoC sweeps the predictable namespace with configurable --probe-seconds and --step-us parameters. In testing, filename recovery succeeds reliably within seconds. Exit code 0 confirms recovery; exit code 2 means file was written but filename not yet found.- Attacker can make HTTP GET requests to the uploads directory
- Directory listing is not required — direct filename probing suffices
- Rate limiting on the target may slow the brute-force sweep
- CDN caching layers may obscure direct file access
/wp-content/uploads/elementor/forms/ in access logsExecute web shell for full server compromise
X-CMD). The web shell executes as the web server user (www-data, apache, nginx), giving the attacker command execution on the underlying server. From here, standard post-exploitation follows: reading wp-config.php for database credentials, dumping the database, pivoting to other services on the host or network, installing persistent backdoors, or injecting malicious JavaScript into served pages for supply-chain attacks against site visitors.- PHP execution is enabled in the uploads directory
- Web shell file has not been quarantined by a security plugin
- Hardened hosts with
php_flag engine offin uploads.htaccessblock execution entirely - Container-based WordPress deployments may limit lateral movement
.php in uploads path, Wordfence real-time firewallreturn/continue desynchronization in validation() and process_field(). Per the noisgate mitigation SLA for CRITICAL, deploy within 3 days. Test in staging first if you have a change-management process, but do not let process delay this beyond the 3-day window given active exploitation.php_flag engine off to /wp-content/uploads/elementor/forms/.htaccess (Apache) or equivalent location block denying .php execution (Nginx). This breaks step 5 of the attack path — even if the PHP file lands on disk, it cannot execute. Deploy within hours as an interim control while patching is staged. This does NOT prevent the file write, so you still have an arbitrary file upload — but it eliminates the RCE impact.admin-ajax.php with .php filenames). Enable managed WordPress WAF rulesets. This blocks step 2 at the network layer. Not a substitute for patching — determined attackers may find bypasses — but effective against automated scanning./wp-content/uploads/elementor/forms/ for any .php files — there should be none in normal operation. Run find /path/to/wp-content/uploads/elementor/forms/ -name '*.php' and investigate any results. Given exploitation began August 19, any unpatched site may already be compromised.- WordPress user role restrictions / capability checks — the vulnerability is unauthenticated, so WordPress's permission model is never consulted. Restricting user roles does nothing.
- Limiting 'Allowed File Types' in the Elementor form settings — the validation bypass skips the extension check entirely, so this setting is never evaluated during the attack.
- Setting the File Upload field max file size to a small value — the validation function exits before reaching the size check, so this control is bypassed along with the extension check.
- Disabling XML-RPC or REST API — the attack goes through
admin-ajax.php, not XML-RPC or the REST API. Disabling those endpoints does not affect this attack vector. - CAPTCHA on the form — Elementor's CAPTCHA validation runs in a separate handler; the file upload validation bypass occurs regardless of CAPTCHA status.
The supporting signals.
| In-the-Wild Exploitation | Confirmed active. Wordfence blocked 190,000+ exploitation attempts between August 19–23, 2026. BleepingComputer, The Hacker News, and SCWorld independently confirmed campaigns deploying PHP web shells. Attackers are targeting sites opportunistically at scale. |
|---|---|
| Proof-of-Concept Availability | Multiple public PoCs. GitHub repos: Boreas37/CVE-2026-32475-PoC (stdlib Python, concurrent uniqid sweep), 4minx/CVE-2026-32475, absholi7ly/Elementor-Pro-Unauthenticated-Arbitrary-File-Upload-to-RCE, 0xBlackash/CVE-2026-32475. Exploit is fully weaponized with automated form recon, upload, filename recovery, and shell execution. |
| EPSS Score | 0.01995 (top ~2% probability of exploitation in 30 days). Given confirmed active exploitation, EPSS is lagging reality — treat this as actively exploited regardless of the percentile. |
| KEV Status | Not listed as of 2026-10-08. Expect CISA addition given confirmed exploitation — KEV listing often lags active campaigns by weeks for non-federal-agency software. |
| CVSS Vector | CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H = 9.0. AV:N (network-reachable), PR:N (no auth), UI:N (no user interaction), S:C (scope change — web shell escapes the WordPress application boundary to the OS). AC:H reflects the uniqid() race, but automated tooling makes this effectively AC:L in practice. |
| Affected Versions | Elementor Pro ≤ 4.2.1 — all prior versions of the Pro plugin with the Forms module are affected. The free Elementor plugin is not affected (no Forms module). |
| Fixed Version | Elementor Pro 4.2.2 (released August 19, 2026). No distro backports apply — this is a commercial WordPress plugin updated via its own license-based updater or WordPress dashboard. |
| Installed Base / Exposure | Elementor Pro has 10 million+ active installations powering 22 million+ sites. Elementor (free+Pro combined) runs on ~32.67% of WordPress sites (HTTP Archive, April 2026). WordPress itself powers ~43% of all websites globally. The intersection — Elementor Pro sites with vulnerable forms — is a subset, but the absolute numbers are massive. |
| Disclosure & Researcher | Discovered by Tin Pham (TF1T) via Patchstack. Reported July 16, 2026; vendor patched July 17; patch validated August 3; public disclosure August 19, 2026. |
| Scanning / Detection | Wordfence released a firewall rule on August 19. Patchstack virtual patch available. Nuclei templates exist for version detection. No specific GreyNoise or Shodan tag identified, but mass scanning is confirmed by the 190K+ blocked attempts. |
Sources.
- Patchstack Advisory — Critical Unauthenticated File Upload to RCE in Elementor Pro
- The Hacker News — Elementor Pro Flaw Could Let Unauthenticated Attackers Upload PHP
- BleepingComputer — Critical Elementor Pro Flaw Exploited to Take Over WordPress Sites
- Boreas37 PoC — CVE-2026-32475 Stdlib Python Exploit
- SecurityOnline — CVE-2026-32475: Elementor Pro RCE Exploited in the Wild
- Wordfence / Really Simple Security — Elementor Pro ≤ 4.2.1 Upload Field Array Validation Bypass
- DEV Community — Active Exploitation Analysis of PHP Web Shell via Array Validation Bypass
- Colorlib — Elementor Statistics 2026: Market Share, Usage & Trends
Why this verdict
- Active exploitation confirmed: 190,000+ attack attempts blocked by Wordfence in the first 5 days post-disclosure. This is not theoretical — attackers are scanning and exploiting at scale right now.
- Weaponized PoCs eliminate AC:H friction: The CVSS vector encodes AC:H for the
uniqid()filename race, but at least four public GitHub repos provide fully automated exploits with concurrent thread pools that reliably recover filenames in seconds. In practice, attack complexity is Low. - Unauthenticated, zero-interaction, network-reachable: The full chain — form discovery through web shell execution — requires no credentials, no CSRF tokens, no user interaction. Any internet-facing WordPress site with a vulnerable Elementor Pro form is a target.
- Massive installed base: 10M+ active Elementor Pro installations. Even if only 10–20% have forms with file upload fields, that's 1–2 million directly vulnerable targets. The absolute exposure surface is enormous.
- Role multiplier: WordPress with Elementor Pro is canonically an internet-facing web application tier. In the typical role, compromise yields: (1) full server-level RCE as the web server user, (2) database credential theft via
wp-config.php, (3) customer PII / payment data exfiltration, (4) supply-chain risk via JavaScript injection into pages served to visitors. In the high-value role — e-commerce sites, customer portals with PII, corporate sites serving software downloads — the blast radius extends to mass data egress and supply-chain compromise affecting downstream visitors. Given that Elementor Pro's core use case is building production customer-facing sites, a significant fraction (well above 1%) of the installed base occupies this high-value web-application role. The chain succeeds fully in these roles. Verdict floor: HIGH, and the active exploitation + unauthenticated RCE + massive exposure pushes above the floor to CRITICAL. - Scope change (S:C) is real: The web shell escapes the WordPress application sandbox to the underlying OS, enabling lateral movement to co-hosted sites, databases, and internal network segments depending on hosting architecture.
Why not higher?
The score is already near the ceiling at 9.2. A 10.0 would require AC:L in the formal vector and trivial, reliable exploitation with no prerequisites. The uniqid() race and the requirement for a specific form configuration (file upload field present and non-required) prevent a perfect 10, even though automated tooling largely negates the race condition.
Why not lower?
Downgrading below CRITICAL would require evidence that the prerequisite form configuration is rare or that PHP execution in uploads is commonly disabled. Neither holds: file upload fields are a standard Elementor Pro Forms feature, the 'Required' toggle defaults to off, and most WordPress hosting environments allow PHP execution in uploads by default. The confirmed active exploitation at scale (190K+ attempts) eliminates any theoretical doubt about exploitability. Managed hosts that disable PHP in uploads are a minority of the installed base.
Crowdsourced verification payload.
Run this script on each WordPress host as a user with read access to the WordPress installation directory (typically www-data or root). Invoke with: sudo bash check_cve_2026_32475.sh /var/www/html where the argument is the WordPress root directory. No network access or external dependencies required.
#!/usr/bin/env bash
# CVE-2026-32475 Checker — Elementor Pro Unauthenticated File Upload to RCE
# Usage: bash check_cve_2026_32475.sh /path/to/wordpress
# Exit codes: 0=VULNERABLE, 1=PATCHED, 2=UNKNOWN
set -euo pipefail
WP_ROOT="${1:-}"
if [ -z "$WP_ROOT" ] || [ ! -d "$WP_ROOT" ]; then
echo "UNKNOWN — Usage: $0 /path/to/wordpress-root"
exit 2
fi
PLUGIN_DIR="$WP_ROOT/wp-content/plugins/elementor-pro"
# Check if Elementor Pro is installed
if [ ! -d "$PLUGIN_DIR" ]; then
echo "UNKNOWN — Elementor Pro plugin not found at $PLUGIN_DIR"
exit 2
fi
# Extract version from elementor-pro.php header
MAIN_FILE="$PLUGIN_DIR/elementor-pro.php"
if [ ! -f "$MAIN_FILE" ]; then
echo "UNKNOWN — Main plugin file not found: $MAIN_FILE"
exit 2
fi
VERSION=$(grep -i 'Version:' "$MAIN_FILE" | head -1 | sed 's/.*Version:[[:space:]]*//' | tr -d '[:space:]')
if [ -z "$VERSION" ]; then
echo "UNKNOWN — Could not parse version from $MAIN_FILE"
exit 2
fi
echo "Elementor Pro version detected: $VERSION"
# Compare versions — 4.2.2 is the fix
# Using sort -V for version comparison
FIXED_VERSION="4.2.2"
LOWER=$(printf '%s\n%s' "$VERSION" "$FIXED_VERSION" | sort -V | head -1)
if [ "$VERSION" = "$FIXED_VERSION" ] || [ "$LOWER" = "$FIXED_VERSION" ]; then
echo "PATCHED — Elementor Pro $VERSION >= $FIXED_VERSION (CVE-2026-32475 fix)"
# Also check for existing webshells
UPLOAD_DIR="$WP_ROOT/wp-content/uploads/elementor/forms"
if [ -d "$UPLOAD_DIR" ]; then
PHP_FILES=$(find "$UPLOAD_DIR" -name '*.php' -o -name '*.phtml' -o -name '*.pht' 2>/dev/null | head -20)
if [ -n "$PHP_FILES" ]; then
echo "WARNING — Suspicious PHP files found in uploads (possible prior compromise):"
echo "$PHP_FILES"
fi
fi
exit 1
else
echo "VULNERABLE — Elementor Pro $VERSION < $FIXED_VERSION"
echo "CVE-2026-32475: Unauthenticated arbitrary file upload to RCE"
echo "Action: Upgrade to Elementor Pro >= $FIXED_VERSION immediately"
# Check for existing webshells
UPLOAD_DIR="$WP_ROOT/wp-content/uploads/elementor/forms"
if [ -d "$UPLOAD_DIR" ]; then
PHP_FILES=$(find "$UPLOAD_DIR" -name '*.php' -o -name '*.phtml' -o -name '*.pht' 2>/dev/null | head -20)
if [ -n "$PHP_FILES" ]; then
echo "CRITICAL — Suspicious PHP files found in uploads directory (POSSIBLE ACTIVE COMPROMISE):"
echo "$PHP_FILES"
echo "Investigate immediately for webshells."
fi
fi
# Check if PHP execution is disabled in uploads
HTACCESS="$WP_ROOT/wp-content/uploads/elementor/forms/.htaccess"
if [ -f "$HTACCESS" ] && grep -qi 'engine off\|deny from all\|RemoveHandler' "$HTACCESS"; then
echo "NOTE — .htaccess in uploads may disable PHP execution (partial mitigation)"
else
echo "NOTE — No PHP execution restriction detected in uploads directory"
fi
exit 0
fi