CVE-2026-23693

ElementsKit Elementor addons Lite < 3.7.9 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.7.9
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<3.7.9
PublishedFebruary 24, 2026
Last updatedFebruary 24, 2026
Affected pluginelementskit-lite

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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, or module_status_change)
  • Payload Parameters: modules[], settings[], or module_name depending on the sub-action.
  • Authentication: None (Unauthenticated via wp_ajax_nopriv_).
  • Preconditions: A valid WordPress nonce for the ekit_admin_action action must be obtained.

3. Code Flow

  1. The plugin registers the AJAX hooks in libs/framework/ajax-handler.php within the ElementsKit_Lite\Libs\Framework\Ajax_Handler class.
  2. 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' ] );
    
  3. The ekit_admin_action() function is called when a request is made to admin-ajax.php?action=ekit_admin_action.
  4. The function performs a nonce check: check_ajax_referer( 'ekit_admin_action', 'nonce' );.
  5. Vulnerability: After the nonce check, the function routes to sub-actions based on the ekit_action parameter (e.g., save_module_list) without verifying if the user has administrative privileges.
  6. 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.

  1. 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.
  2. Create Trigger Page:
    wp post create --post_type=page --post_title="Ekit Test" --post_status=publish --post_content='[elementskit-icon-pack]'
  3. Navigate and Extract:
    • Navigate to the newly created page.
    • Use browser_eval to extract the nonce from the localized JS variable.
    • JS Variable: window.ekit_config?.nonce or window.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.

  1. Request Tool: http_request
  2. URL: {{BASE_URL}}/wp-admin/admin-ajax.php
  3. Method: POST
  4. Headers: Content-Type: application/x-www-form-urlencoded
  5. Body:
    action=ekit_admin_action&ekit_action=save_module_list&nonce={{NONCE}}&modules[header-footer]=inactive
    
  6. Expected Response: A JSON response indicating success (e.g., {"success": true}).

6. Test Data Setup

  1. Install Plugin: Ensure ElementsKit Lite version < 3.7.9 is active.
  2. Create Post:
    wp post create --post_type=page --post_title="Exploit Page" --post_status=publish --post_content='[elementskit-icon-pack]'
    
  3. Verify Initial State:
    wp option get elementskit_lite_module_list
    
    (Confirm header-footer is currently active or not explicitly inactive).

7. Expected Results

  • The admin-ajax.php request returns a 200 OK with a success JSON body.
  • The database option elementskit_lite_module_list is updated to include header-footer => inactive.
  • Unauthenticated users successfully triggered a state change that should require manage_options capability.

8. Verification Steps

  1. Check Plugin Option:
    wp option get elementskit_lite_module_list --format=json
    
    Verify that the header-footer key is set to inactive.
  2. 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=inactive
  • ekit_action=save_settings&settings[general][tracking]=active
  • If the nonce is not found in ekit_config, check for elementskit_module_vars or search the page source for any key named nonce within a JSON object.
  • If wp_ajax_nopriv_ is missing but the CVSS claims PR:N, look for a REST API endpoint: /wp-json/elementskit/v1/... that might call the same underlying vulnerable function.
Research Findings
Static analysis — not yet PoC-verified

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

--- a/libs/framework/ajax-handler.php
+++ b/libs/framework/ajax-handler.php
@@ -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.