ElementInvader Addons for Elementor <= 1.4.1 - Missing Authorization
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:NTechnical Details
<=1.4.1Source Code
WordPress.org SVNThis 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_cancheck.
3. Code Flow (Inferred)
- Registration: The plugin uses
add_action( 'wp_ajax_...', 'callback_function' )in an admin-related class (likelyincludes/admin/class-admin.phporincludes/class-ei-ajax.php). - Trigger: An authenticated user sends a POST request to
admin-ajax.phpwith the correspondingaction. - Bypass: The
callback_functionmight check a nonce usingcheck_ajax_referer()orwp_verify_nonce(), but it fails to callcurrent_user_can(). - 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.
- Locate the Action: Search for the registration:
grep -rn "wp_ajax_" . - Check for Nonce Localization: Search for
wp_localize_scriptto see where the nonce is passed to the frontend:grep -rn "wp_localize_script" . - Identify the Variable: Look for the JS object name (e.g.,
ei_admin_data) and the key (e.g.,nonce). - 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. - 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:
- 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. - 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]
- URL:
- Execute: Use
http_requestas the Subscriber.
6. Test Data Setup
- Plugin Installation: Ensure ElementInvader Addons for Elementor <= 1.4.1 is installed.
- User Creation:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password - 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 OKor 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:
- Check Option:
wp option get [TARGET_OPTION_NAME] - Compare: Confirm the value matches the
MALICIOUS_VALUEsent in the exploit. - 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:
- Template Import: Check for actions like
ei_import_template. Unauthorized template importing could lead to Stored XSS. - Notice Dismissal: Check
ei_dismiss_notice. While low severity, it confirms the Missing Authorization pattern. - 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_callbackfunction for capability checks.
- Search:
Recommended Tool Sequence for the Agent:
ls -Rto map the plugin structure.grep -rn "wp_ajax_"to find handlers.catthe file containing the callback to check forcurrent_user_can.grep -rn "wp_create_nonce"to find the nonce action string.grep -rn "wp_localize_script"to find where the nonce is exposed.wp user createto set up the Subscriber.browser_navigateandbrowser_evalto grab the nonce as the Subscriber.http_requestto execute the payload.wp option getto verify.
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
@@ -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.