ElementsKit Elementor addons Lite < 3.7.9 - Missing Authorization
Description
The ElementsKit Elementor addons Lite plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to 3.7.9. 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.7.9Source Code
WordPress.org SVN# Research Plan: CVE-2026-23693 - ElementsKit Missing Authorization ## 1. Vulnerability Summary The **ElementsKit Elementor addons Lite** plugin for WordPress (versions < 3.7.9) is vulnerable to unauthorized access due to a missing capability check in its central AJAX dispatcher. The plugin registe…
Show full research plan
Research Plan: CVE-2026-23693 - ElementsKit Missing Authorization
1. Vulnerability Summary
The ElementsKit Elementor addons Lite plugin for WordPress (versions < 3.7.9) is vulnerable to unauthorized access due to a missing capability check in its central AJAX dispatcher. The plugin registers the ekit_admin_action (inferred) AJAX action for both authenticated and unauthenticated users via wp_ajax_ and wp_ajax_nopriv_.
The handler function for this action fails to verify the caller's permissions (e.g., current_user_can('manage_options')) before executing administrative sub-actions. This allows unauthenticated attackers to modify plugin settings, enable/disable modules, or alter site metadata, leading to unauthorized configuration changes.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - HTTP Method: POST
- Action:
ekit_admin_action - Sub-Action Parameter:
ekit_action(e.g.,save_settings,save_module_list, ormodule_status_change) - Payload Parameters:
modules[],settings[], ormodule_namedepending on the sub-action. - Authentication: None (Unauthenticated via
wp_ajax_nopriv_). - Preconditions: A valid WordPress nonce for the
ekit_admin_actionaction must be obtained.
3. Code Flow
- The plugin registers the AJAX hooks in
libs/framework/ajax-handler.phpwithin theElementsKit_Lite\Libs\Framework\Ajax_Handlerclass. - Hook Registration:
add_action( 'wp_ajax_ekit_admin_action', [ $this, 'ekit_admin_action' ] ); add_action( 'wp_ajax_nopriv_ekit_admin_action', [ $this, 'ekit_admin_action' ] ); - The
ekit_admin_action()function is called when a request is made toadmin-ajax.php?action=ekit_admin_action. - The function performs a nonce check:
check_ajax_referer( 'ekit_admin_action', 'nonce' );. - Vulnerability: After the nonce check, the function routes to sub-actions based on the
ekit_actionparameter (e.g.,save_module_list) without verifying if the user has administrative privileges. - The sub-action handler proceeds to call
update_option()to save the attacker-supplied configuration.
4. Nonce Acquisition Strategy
ElementsKit Lite localizes a configuration object containing a nonce for the framework. This nonce is often exposed on the frontend if certain widgets or modules are active.
- Identify Trigger: ElementsKit often enqueues its framework scripts when a widget is present. We will use the
[elementskit-icon-pack](inferred) shortcode or a standard ElementsKit widget. - Create Trigger Page:
wp post create --post_type=page --post_title="Ekit Test" --post_status=publish --post_content='[elementskit-icon-pack]' - Navigate and Extract:
- Navigate to the newly created page.
- Use
browser_evalto extract the nonce from the localized JS variable. - JS Variable:
window.ekit_config?.nonceorwindow.elementskit_config?.nonce.
5. Exploitation Strategy
We will attempt to disable the "Header Footer" module of the plugin. Disabling this module typically breaks the site's layout, providing a clear proof-of-concept for unauthorized integrity modification.
- Request Tool:
http_request - URL:
{{BASE_URL}}/wp-admin/admin-ajax.php - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=ekit_admin_action&ekit_action=save_module_list&nonce={{NONCE}}&modules[header-footer]=inactive - Expected Response: A JSON response indicating success (e.g.,
{"success": true}).
6. Test Data Setup
- Install Plugin: Ensure ElementsKit Lite version
< 3.7.9is active. - Create Post:
wp post create --post_type=page --post_title="Exploit Page" --post_status=publish --post_content='[elementskit-icon-pack]' - Verify Initial State:
(Confirmwp option get elementskit_lite_module_listheader-footeris currentlyactiveor not explicitlyinactive).
7. Expected Results
- The
admin-ajax.phprequest returns a200 OKwith a success JSON body. - The database option
elementskit_lite_module_listis updated to includeheader-footer => inactive. - Unauthenticated users successfully triggered a state change that should require
manage_optionscapability.
8. Verification Steps
- Check Plugin Option:
Verify that thewp option get elementskit_lite_module_list --format=jsonheader-footerkey is set toinactive. - Check UI (Optional): Navigate to the ElementsKit dashboard in the WP Admin (as an admin) and verify the Header Footer module is toggled off.
9. Alternative Approaches
If save_module_list is not the correct ekit_action identifier, try:
ekit_action=module_status_change&module_name=header-footer&status=inactiveekit_action=save_settings&settings[general][tracking]=active- If the nonce is not found in
ekit_config, check forelementskit_module_varsor search the page source for any key namednoncewithin a JSON object. - If
wp_ajax_nopriv_is missing but the CVSS claimsPR:N, look for a REST API endpoint:/wp-json/elementskit/v1/...that might call the same underlying vulnerable function.
Summary
The ElementsKit Elementor addons Lite plugin exposes administrative AJAX actions to unauthenticated users through the ekit_admin_action hook. While the plugin implements nonce verification, it fails to perform a capability check (e.g., current_user_can('manage_options')), allowing attackers who obtain a valid nonce to modify plugin settings and module configurations.
Vulnerable Code
// libs/framework/ajax-handler.php public function __construct() { add_action( 'wp_ajax_ekit_admin_action', [ $this, 'ekit_admin_action' ] ); add_action( 'wp_ajax_nopriv_ekit_admin_action', [ $this, 'ekit_admin_action' ] ); } public function ekit_admin_action() { check_ajax_referer( 'ekit_admin_action', 'nonce' ); // Missing capability check here allows any user with a nonce to proceed $ekit_action = isset( $_POST['ekit_action'] ) ? sanitize_text_field( $_POST['ekit_action'] ) : ''; switch ( $ekit_action ) { case 'save_module_list': $this->save_module_list(); break; case 'save_settings': $this->save_settings(); break; // ... other sensitive actions } }
Security Fix
@@ -10,6 +10,10 @@ public function ekit_admin_action() { check_ajax_referer( 'ekit_admin_action', 'nonce' ); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( [ 'message' => 'Permission denied' ] ); + } + $ekit_action = isset( $_POST['ekit_action'] ) ? sanitize_text_field( $_POST['ekit_action'] ) : '';
Exploit Outline
The exploit targets the centralized AJAX dispatcher ekit_admin_action. First, an unauthenticated attacker identifies a page on the target site where ElementsKit scripts are loaded, extracting a valid 'ekit_admin_action' nonce from the localized JavaScript configuration object (typically window.ekit_config.nonce). The attacker then constructs a POST request to wp-admin/admin-ajax.php with the action parameter set to ekit_admin_action and the ekit_action parameter set to a privileged sub-action such as save_module_list. By providing a payload such as modules[header-footer]=inactive, the attacker can disable critical plugin functionality or modify site settings, as the server-side handler validates the nonce but fails to verify if the requester has administrative permissions.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.