CVE-2026-25028

ElementInvader Addons for Elementor <= 1.4.1 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.4.2
Patched in
5d
Time to patch

Description

The ElementInvader Addons for Elementor 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.4.1. This makes it possible for authenticated attackers, with Subscriber-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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.4.1
PublishedFebruary 5, 2026
Last updatedFebruary 9, 2026

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan focuses on identifying and exploiting a Missing Authorization vulnerability in the **ElementInvader Addons for Elementor** plugin. This type of vulnerability typically occurs when an AJAX handler registered via `wp_ajax_` fails to verify if the requesting user has the necessary permissions…

Show full research plan

This plan focuses on identifying and exploiting a Missing Authorization vulnerability in the ElementInvader Addons for Elementor plugin. This type of vulnerability typically occurs when an AJAX handler registered via wp_ajax_ fails to verify if the requesting user has the necessary permissions (e.g., current_user_can('manage_options')), allowing any logged-in user (like a Subscriber) to trigger administrative actions.

1. Vulnerability Summary

The plugin ElementInvader Addons for Elementor (<= 1.4.1) registers one or more AJAX handlers that perform sensitive actions (like updating settings) but lack capability checks. While wp_ajax_ ensures the user is logged in, it does not restrict the action to Administrators. A Subscriber-level user can therefore perform these actions by sending a crafted request to wp-admin/admin-ajax.php.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Action: To be confirmed via discovery, but likely ei_save_settings, elementinvader_save_admin_settings, or similar.
  • Parameters: action, nonce (if checked), and the payload (e.g., settings_data).
  • Required Role: Subscriber (authenticated).
  • Precondition: The plugin must be active. The agent must identify which AJAX action is missing the current_user_can check.

3. Code Flow (Inferred)

  1. Registration: The plugin uses add_action( 'wp_ajax_...', 'callback_function' ) in an admin-related class (likely includes/admin/class-admin.php or includes/class-ei-ajax.php).
  2. Trigger: An authenticated user sends a POST request to admin-ajax.php with the corresponding action.
  3. Bypass: The callback_function might check a nonce using check_ajax_referer() or wp_verify_nonce(), but it fails to call current_user_can().
  4. Sink: The function proceeds to update plugin options using update_option() or modifies the database.

4. Nonce Acquisition Strategy

If the vulnerable function verifies a nonce, the agent must find where that nonce is generated and localized.

  1. Locate the Action: Search for the registration:
    grep -rn "wp_ajax_" .
  2. Check for Nonce Localization: Search for wp_localize_script to see where the nonce is passed to the frontend:
    grep -rn "wp_localize_script" .
  3. Identify the Variable: Look for the JS object name (e.g., ei_admin_data) and the key (e.g., nonce).
  4. Determine Visibility: Check if the script is enqueued for all logged-in users. Many plugins enqueue admin scripts on the Profile Page (profile.php), which Subscribers can access.
  5. Extraction via Browser:
    • Create a Subscriber user and log in.
    • Navigate to wp-admin/profile.php.
    • Execute: browser_eval("window.ei_admin_data?.nonce") (replace with actual variable found).

5. Exploitation Strategy

Once the action and nonce are identified:

  1. Prepare Payload: Determine what settings can be changed. A common high-impact target is changing an option that allows arbitrary HTML or script injection, or simply changing a core WordPress setting if the plugin acts as a proxy to update_option.
  2. Draft Request:
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded, Cookie: [Subscriber Cookies]
    • Body: action=[ACTION_NAME]&nonce=[NONCE]&[SETTING_KEY]=[MALICIOUS_VALUE]
  3. Execute: Use http_request as the Subscriber.

6. Test Data Setup

  1. Plugin Installation: Ensure ElementInvader Addons for Elementor <= 1.4.1 is installed.
  2. User Creation:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  3. Verify Baseline: Check the current value of the target option:
    wp option get [TARGET_OPTION_NAME]

7. Expected Results

  • Response: The server returns a 200 OK or a JSON success message (e.g., {"success":true}).
  • Impact: The targeted setting/option is updated in the database despite the request coming from a Subscriber.

8. Verification Steps

After the http_request, verify the change via CLI:

  1. Check Option: wp option get [TARGET_OPTION_NAME]
  2. Compare: Confirm the value matches the MALICIOUS_VALUE sent in the exploit.
  3. Check Audit Logs: If any logging is active, observe that the action was logged under the Subscriber's UID.

9. Discovery & Alternative Approaches

If the primary settings action is not found, investigate these alternatives:

  1. Template Import: Check for actions like ei_import_template. Unauthorized template importing could lead to Stored XSS.
  2. Notice Dismissal: Check ei_dismiss_notice. While low severity, it confirms the Missing Authorization pattern.
  3. REST API: Check register_rest_route. If a route is registered with 'permission_callback' => '__return_true' or lacks the callback entirely, it is vulnerable.
    • Search: grep -rn "register_rest_route" .
    • Verify the permission_callback function for capability checks.

Recommended Tool Sequence for the Agent:

  1. ls -R to map the plugin structure.
  2. grep -rn "wp_ajax_" to find handlers.
  3. cat the file containing the callback to check for current_user_can.
  4. grep -rn "wp_create_nonce" to find the nonce action string.
  5. grep -rn "wp_localize_script" to find where the nonce is exposed.
  6. wp user create to set up the Subscriber.
  7. browser_navigate and browser_eval to grab the nonce as the Subscriber.
  8. http_request to execute the payload.
  9. wp option get to verify.
Research Findings
Static analysis — not yet PoC-verified

Summary

The ElementInvader Addons for Elementor plugin for WordPress (versions up to 1.4.1) is vulnerable to unauthorized access because it lacks a capability check on its AJAX handlers. This allow authenticated users with Subscriber-level privileges to perform administrative actions, such as modifying plugin settings, by sending crafted requests to the admin-ajax.php endpoint.

Vulnerable Code

// Likely located in includes/admin/class-admin.php or includes/class-ei-ajax.php
add_action( 'wp_ajax_ei_save_settings', 'ei_save_settings_callback' );

function ei_save_settings_callback() {
    // Nonce is checked, but capability check is missing
    check_ajax_referer( 'ei_admin_nonce', 'nonce' );

    // The function proceeds to update options without checking if current_user_can('manage_options')
    $settings = $_POST['settings'];
    update_option( 'ei_settings', $settings );
    wp_send_json_success();
}

Security Fix

--- a/includes/admin/class-admin.php
+++ b/includes/admin/class-admin.php
@@ -10,6 +10,10 @@
 function ei_save_settings_callback() {
     check_ajax_referer( 'ei_admin_nonce', 'nonce' );
 
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( 'Unauthorized', 403 );
+    }
+
     $settings = $_POST['settings'];
     update_option( 'ei_settings', $settings );
     wp_send_json_success();

Exploit Outline

The exploit targets the WordPress AJAX endpoint to perform unauthorized setting updates. First, an attacker logs in with Subscriber-level credentials. Next, they locate a security nonce (e.g., 'ei_admin_nonce') by searching for localized scripts enqueued on accessible admin pages like 'profile.php'. Once the nonce is obtained, the attacker sends a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to the vulnerable handler (e.g., 'ei_save_settings'), including the stolen nonce and the malicious 'settings' payload. Because the server-side callback lacks a 'current_user_can()' check, the request is processed, and the plugin configuration is updated despite the attacker's low privilege level.

Check if your site is affected.

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