ctipilot.ch
← Back to the live brief
HIGHCVE-2026-32475NATOB1vulnerability

Elementor Pro (WordPress): unauthenticated arbitrary file upload to RCE via a validator/mover desynchronization in the Forms File Upload field (CVE-2026-32475, CVSS 9.0)

first published 2026-08-28 05:45 UTCrun 2026-08-28T0409Z-intel2 sourcesmulti-source

CVE-2026-32475 (CVSS 9.0) affects Elementor Pro ≤4.2.1, fixed in 4.2.2 (patched 19 August, patch reviewed and confirmed effective by Patchstack). The Forms module's File Upload field (modules/forms/fields/upload.php) validates an upload's extension in one loop (validation()) and moves accepted files to a public directory in a separate loop (process_field()) — and the two loops disagree about what an empty file entry (UPLOAD_ERR_NO_FILE) means. validation() does if (!required && UPLOAD_ERR_NO_FILE) return; — an empty first entry makes it abandon checking the entire field, including every later entry. process_field() instead does if (UPLOAD_ERR_NO_FILE) continue; — it skips only the empty entry and still moves everything after it: "an empty first entry makes validation() return before it ever type-checks the .php entry that follows it. process_field(), meanwhile, only continues past that empty entry and moves the .php one anyway. The validator reports a clean submission because it stopped reading; the mover proceeds because it did not" (Patchstack, 2026-08-19).

Submitting two file parts for one File Upload field — an empty first part, then a .php payload as the second — makes the validator report a clean submission (it stopped reading before reaching the .php entry) while the mover still processes and moves that .php file. The blocklist check (is_file_type_valid(), which does correctly reject php/phtml/asp/etc.) never runs against the payload at all: "the .php file lands in wp-content/uploads/elementor/forms/, a public, web-accessible directory, letting a fully unauthenticated visitor place executable PHP on the server and, by requesting the file directly, achieve remote code execution" (Patchstack, 2026-08-19).

The only prerequisite is any published Elementor page containing a Form widget with a File Upload field (Required toggle off by default) — an everyday configuration such as a job-application, support-ticket, or "attach a document" form. Every value the exploit needs (post_id, form_id, the field's form_fields[ID] name) is visible in the page's public HTML, and the request goes through the elementor_pro_forms_send_form AJAX action with no cookie or nonce required. Recovering the stored filename — always uniqid().extension, discarding the submitted name — is cheap: the 8 hex "seconds" digits come straight from the server's own Date: response header, leaving only 5 hex microsecond digits to brute-force, or, on forms with an autoresponder email action enabled (common on the same job-application/support-ticket forms), Elementor's own default notification template discloses the exact upload URL to the attacker-controlled email address with zero brute-forcing. The fix in 4.2.2 synchronizes the two loops' empty-entry handling and additionally re-checks the extension inside process_field() itself, immediately before the move, so the blocklist now guards the sink directly.

Triage: any .php (or other server-executable) file under wp-content/uploads/elementor/forms/ is a compromise indicator regardless of current patch level. On the request side, form submissions to elementor_pro_forms_send_form carrying multiple file parts for a single File Upload field — one empty, one non-empty — are the delivery shape; a legitimate single-file upload never needs a leading empty part, so its presence has no benign explanation.

An empty first entry makes validation() return before it ever type-checks the .php entry that follows it. process_field(), meanwhile, only continues past that empty entry and moves the .php one anyway. The validator reports a clean submission because it stopped reading; the mover proceeds because it did not.

The .php file lands in wp-content/uploads/elementor/forms/, a public, web-accessible directory, letting a fully unauthenticated visitor place executable PHP on the server and, by requesting the file directly, achieve remote code execution.

Patchstack 2026-08-19

Defender actions

  • Upgrade Elementor Pro to 4.2.2 or later on every WordPress site now, and audit wp-content/uploads/elementor/forms/ for any .php file as a compromise check regardless of current patch level — any published page with a Form widget carrying a File Upload field (Required toggle off by default) has been exposed since before this disclosure.

ATT&CK mapping

2 techniques mapped from the cited reporting · MITRE ATT&CK v19.2

Initial Access TA0001
T1190Exploit Public-Facing Application

Adversaries may attempt to exploit a weakness in an Internet-facing host or system to initially access a network. The weakness in the system can be a software bug, a temporary glitch, or a misconfiguration.

overlap matrix · ATT&CK page ↗

Persistence TA0003
T1505.003Server Software Component: Web Shell

Adversaries may backdoor web servers with web shells to establish persistent access to systems. A Web shell is a Web script that is placed on an openly accessible Web server to allow an adversary to access the Web server as a gateway into a network. A Web shell may provide a set of functions to execute or a command-line interface on the system that hosts the Web server.

overlap matrix · ATT&CK page ↗

PROVENANCE

AI-generated · no human review · this permalink is the shareable record for the finding · verify operationally critical claims against the linked primary source.