Elementor Pro file upload flaw lets attackers run code

Elementor Pro file upload flaw lets attackers run code

An unauthenticated file upload bug in Elementor Pro up to 4.2.1 lets anyone run code on a WordPress site. Version 4.2.2 fixes it.

Elementor Pro, the paid extension of the widely used Elementor page builder for WordPress, carried a critical file upload flaw that let anyone at all place a working program on a website and run it. The bug is tracked as CVE-2026-32475 and scored 9.0 on the CVSS scale, a standard 0 to 10 severity rating where a higher number means a more dangerous flaw. It affects Elementor Pro version 4.2.1 and earlier, and the fixed version, 4.2.2, was released on 19 August 2026. The vulnerability was discovered and reported to Patchstack by Tin Pham, known as TF1T, and Patchstack published its technical write-up of the issue on the same day it says the patch shipped. Patchstack states that it has issued mitigation rules to protect against exploitation of the flaw.

For anyone who does not work with websites daily: WordPress is the software that runs a very large share of the world's sites, and a page builder is a plugin, meaning an add-on piece of software, that lets an owner assemble pages visually instead of writing code. Elementor is one of the most popular page builders, and Elementor Pro is its commercial edition. Among the features Elementor Pro adds is a Forms widget, which lets a site owner build contact forms, job application forms and support ticket forms inside the editor, including a File Upload field so that a visitor can attach a document. That field is where the flaw lives, inside the plugin's Forms module.

Patchstack's analysis describes the bug as a mismatch between two loops in the file modules/forms/fields/upload.php. When a form is submitted, two separate passes read the same list of uploaded file entries. The first, a method called validation(), checks each entry's file extension against a list of allowed types and against a blocklist of disallowed ones. The second, a method called process_field(), takes each valid entry and moves the file into a public directory. The two passes disagree about what an empty file entry means. An empty entry is an upload part with a blank filename, which PHP reports as UPLOAD_ERR_NO_FILE. PHP is the programming language WordPress itself is written in.

In the validation loop, an empty entry met while the field is not marked as required causes the whole method to stop and return, so every later entry in that same submission goes unchecked. In the processing loop, the same empty entry is simply skipped and the loop carries on. An attacker can therefore send two file parts for the same field: an empty first entry with a blank filename, followed by a .php file. Validation stops reading at the first entry and reports a clean submission. The mover skips that first entry and moves the .php file anyway. The distance between a working defence and this bug, as Patchstack puts it, is one keyword.

The intended protection is a function called is_file_type_valid(), which requires an uploaded file's extension to appear on an allowed list and rejects it if it also appears on a hardcoded blocklist. That blocklist explicitly names php, php3, php4, php5, php6, phps, php7, phtml, shtml, pht, swf, html, asp, aspx, cmd, csh, bat, htm, hta, jar, exe and com, among others. Patchstack notes that the check itself is sound. It simply never runs.

The move step is where the damage happens. process_field() reads the extension from the submitted filename, builds a new name with PHP's uniqid() function, and moves the file into the plugin's public forms directory. The submitted filename is thrown away completely. Only the extension survives into the stored name. That detail rules out several other tricks. A double extension such as shell.php.jpg is harmless here, because the file would be saved as a random name ending in .jpg. An uploaded .htaccess file is equally inert, because it becomes a randomly named .htaccess file rather than a directory configuration file. Only the final extension counts, and the loop mismatch is enough to slip it past the check. The result is a .php file sitting in wp-content/uploads/elementor/forms/, a folder that is publicly reachable over the web. Anyone can then request that address directly and have the server run the file. That is remote code execution: the attacker's own code executing on the site's server.

The requirements for an attack are minimal. The target site needs at least one published page containing an Elementor form with a File Upload field, which Patchstack describes as an extremely common, everyday configuration. Job application forms, forms asking for a photo, ID or receipt, and support ticket attachments all use it. The field's Required toggle is off by default, so no hardened or unusual setting is needed. Everything the attacker needs to build the request, the post_id, the form_id (Elementor's internal identifier for the form widget) and the upload field's input name, is visible in the public page HTML to any visitor. The upload is handled through the elementor_pro_forms_send_form AJAX action, with no cookies and no nonce required. A nonce is a one-time security token that WordPress normally uses to verify that a request came from a legitimate page.

One detail complicates the attack: the upload response does not return the file's path, so the name has to be worked out. That is cheaper than it sounds, because uniqid() is not random but time based. It produces 13 hexadecimal characters, of which eight encode the Unix timestamp in whole seconds and five encode microseconds. Since the server's own Date response header supplies the seconds directly, only the five microsecond characters have to be guessed, and Patchstack notes that even that space can be narrowed to the window around the exploit request itself. There is also a route that requires no guessing at all. Elementor Pro's default notification template, [all-fields], renders every submitted field, including a line with the exact URL of the uploaded file. Where a form also has a second autoresponder email action enabled, which Patchstack says is common on precisely the job application and support ticket forms that carry file upload fields, that email is sent to the address the attacker submitted, disclosing the precise upload URL.

The fix in version 4.2.2 makes the two loops agree about what an empty file entry means, so an entry can no longer be ignored by the validator while still being picked up by the mover. Patchstack adds that current versions also re-check the extension inside process_field() itself, immediately before the file is moved, so the blocklist now guards the destination directly instead of only the validation pass.

Because this flaw is unauthenticated and leaves a file behind on disk, updating closes the hole but does not undo an attempt that already succeeded. Sites that ran a vulnerable version with a public form containing a File Upload field should also look through wp-content/uploads/elementor/forms/ for anything that is not one of the document or image types their forms actually accept, and in particular for files ending in .php.

How to Protect Yourself

  1. Open your WordPress dashboard, go to the Plugins page and update Elementor Pro to version 4.2.2 or newer today if it is installed.
  2. If you are not sure whether your site uses Elementor Pro, ask whoever built or hosts it, or check the Plugins list in your WordPress dashboard.
  3. If your website forms do not need file attachments, remove the File Upload field from them, since that is the part of the form this problem uses.
  4. Ask your hosting provider or developer to look in the folder where your form uploads are stored for any unexpected files that end in .php, which is the ending used by the code that runs your site.
  5. Consider turning on automatic updates for your website's add-on software, so that security fixes like this one install themselves instead of waiting for you.
  6. If your site ran an older version with a public form that accepts file uploads, change your WordPress admin password and ask a developer to check the site for anything unusual.

Vulnerabilities & Fixes

Terms Explained

  • WordPress The free software that runs a very large share of the world's websites and lets owners publish pages and posts without programming.
  • plugin An add-on piece of software you install on a website to give it extra features, such as a contact form or a page builder.
  • remote code execution When an outsider manages to make a website's server run instructions they wrote themselves, effectively taking control of the machine.
  • unauthenticated Describing an attack that needs no username, password or account on the site, so any stranger on the internet can attempt it.
  • CVE-2026-32475 The official reference number given to this particular security flaw so that vendors, researchers and tools all refer to the same issue.
  • CVSS A standard 0 to 10 scoring system for how serious a security flaw is, where higher numbers mean greater danger.
  • nonce A one-time code that a website attaches to a request to prove it really came from its own page and not from an outsider.
  • PHP The programming language that WordPress and many website files are written in, and the language of files ending in .php.

Related AEU services