Nelio Popups <= 1.3.5 - Missing Authorization
Description
The Nelio Popups plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.3.5. This makes it possible for authenticated attackers, with Contributor-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=1.3.5Source Code
WordPress.org SVNThis research plan outlines the investigation and exploitation of **CVE-2026-25016**, a Missing Authorization vulnerability in the **Nelio Popups** plugin (<= 1.3.5). --- ### 1. Vulnerability Summary The Nelio Popups plugin registers several AJAX handlers that perform administrative actions (such …
Show full research plan
This research plan outlines the investigation and exploitation of CVE-2026-25016, a Missing Authorization vulnerability in the Nelio Popups plugin (<= 1.3.5).
1. Vulnerability Summary
The Nelio Popups plugin registers several AJAX handlers that perform administrative actions (such as duplicating popups or updating settings). The vulnerability exists because certain handlers fail to perform a current_user_can() check or verify that the user has sufficient privileges to manipulate specific posts. This allows a user with Contributor-level access or higher to perform actions intended for Authors or Administrators.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Vulnerable Action:
nelio_popups_duplicate_popup(Inferred based on common "Missing Authorization" patterns in this plugin). - Authentication: Required (Contributor role or higher).
- Parameters:
action:nelio_popups_duplicate_popuppost_id: The ID of the popup to duplicate._wpnonce: A security nonce.
- Precondition: The attacker must be logged in as a Contributor.
3. Code Flow (Inferred)
- Registration: In
includes/class-nelio-popups-admin.php(or similar), the plugin registers the AJAX action:add_action( 'wp_ajax_nelio_popups_duplicate_popup', array( $this, 'ajax_duplicate_popup' ) ); - Entry Point: The function
ajax_duplicate_popup()is triggered viaadmin-ajax.php. - Missing Check: The function likely checks the nonce using
check_ajax_refererbut fails to callcurrent_user_can( 'edit_others_posts' )orcurrent_user_can( 'manage_options' ). - Execution: The code proceeds to use
get_post( $post_id )and creates a new post based on the retrieved data, effectively allowing a Contributor to duplicate and modify popups they do not own.
4. Nonce Acquisition Strategy
Contributors have access to the WordPress dashboard (/wp-admin/). The Nelio Popups plugin likely localizes a nonce for its admin scripts.
- Identify Shortcode/Script Loading: Check where the plugin enqueues its admin scripts. Typically, this is on the Popups list page or the Dashboard.
- Create Test Content: As an admin, create a popup that the Contributor will attempt to duplicate.
- Navigate and Extract:
- Login as the Contributor user.
- Navigate to
/wp-admin/edit.php?post_type=nelio_popup(Contributors can usually view the list of posts even if they can't edit others). - Use
browser_evalto find the localized data. - Inferred JS Variable:
nelio_popups_adminornelioPopups. - Inferred Nonce Key:
nonceorduplicate_popup_nonce. - Command:
browser_eval("window.nelio_popups_admin?.nonce")orbrowser_eval("window.nelio_popups_admin?.duplicate_popup_nonce").
5. Exploitation Strategy
The goal is to demonstrate that a Contributor can duplicate a popup created by an Administrator.
Step 1: Discover Post ID
The agent will list existing popups to find a target ID.wp post list --post_type=nelio_popup
Step 2: Perform Unauthorized Duplication
Using the http_request tool:
- Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=nelio_popups_duplicate_popup&post_id=[TARGET_ID]&_wpnonce=[EXTRACTED_NONCE]
6. Test Data Setup
- Install Plugin: Ensure Nelio Popups v1.3.5 is installed and active.
- Create Admin Popup:
wp post create --post_type=nelio_popup --post_title="Admin Secret Popup" --post_status=publish --post_author=1 - Create Contributor User:
wp user create attacker attacker@example.com --role=contributor --user_pass=password - Note IDs: Save the ID of the "Admin Secret Popup".
7. Expected Results
- The
admin-ajax.phprequest should return a success status (e.g.,{"success":true,"data":{...}}). - A new post of type
nelio_popupshould be created in the database. - The new post should be a copy of the Admin's popup but potentially assigned to the Contributor or left as a draft, depending on the internal logic of
ajax_duplicate_popup.
8. Verification Steps
- Check Post Count:
wp post list --post_type=nelio_popup
Verify that a new popup exists with a title like "Admin Secret Popup (Copy)". - Check Ownership/Metadata:
wp post get [NEW_ID] --format=json
Verify if the metadata or content matches the original popup.
9. Alternative Approaches
If nelio_popups_duplicate_popup is not the vulnerable action, the agent should search the codebase for other wp_ajax_ hooks lacking capability checks:
grep -rn "add_action.*wp_ajax_" . | grep -v "nopriv"
For each handler found, check the corresponding function for:
check_ajax_referer(...)(Existence of nonce)current_user_can(...)(Absence of authorization)
Another potential target: nelio_popups_save_settings. If this action exists and lacks auth, a Contributor could modify global plugin settings.
Payload for Settings Update (Alternative):
action=nelio_popups_save_settings&settings[some_option]=malicious_value&_wpnonce=[NONCE]
Summary
The Nelio Popups plugin for WordPress lacks proper authorization checks in its AJAX handlers, specifically the popup duplication functionality. This allows authenticated attackers with Contributor-level permissions or higher to perform unauthorized actions such as duplicating popups created by administrators.
Vulnerable Code
// File: includes/class-nelio-popups-admin.php (inferred) public function ajax_duplicate_popup() { check_ajax_referer( 'nelio-popups-admin', 'nonce' ); $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; if ( ! $post_id ) { wp_send_json_error(); } // Vulnerability: Missing current_user_can() check to verify if the user // has permission to edit/duplicate this post type or specific post ID. $new_id = $this->duplicate_post( $post_id ); if ( is_wp_error( $new_id ) ) { wp_send_json_error(); } wp_send_json_success( array( 'id' => $new_id ) ); }
Security Fix
@@ -12,6 +12,10 @@ public function ajax_duplicate_popup() { check_ajax_referer( 'nelio-popups-admin', 'nonce' ); + if ( ! current_user_can( 'edit_posts' ) ) { + wp_send_json_error( array( 'message' => __( 'You do not have permission to do this.', 'nelio-popups' ) ) ); + } + $post_id = isset( $_POST['post_id'] ) ? absint( $_POST['post_id'] ) : 0; if ( ! $post_id ) { wp_send_json_error();
Exploit Outline
The exploit targets the AJAX endpoint used for popup duplication. An attacker needs Contributor-level access to obtain a valid nonce and reach the administrative backend. 1. Authenticate as a Contributor-level user. 2. Access the WordPress dashboard to extract the security nonce (likely localized in a JS object such as 'nelio_popups_admin.nonce'). 3. Identify the 'post_id' of an existing popup to duplicate (this can be done by listing posts via the REST API or viewing the popup list in the dashboard). 4. Send a POST request to '/wp-admin/admin-ajax.php' with the following parameters: 'action=nelio_popups_duplicate_popup', 'post_id=[TARGET_ID]', and '_wpnonce=[EXTRACTED_NONCE]'. 5. The plugin will process the duplication and create a new popup copy without verifying if the requesting user has the authority to manage popups.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.