Bit Assist <= 1.5.11 - Missing Authorization
Description
The Chat Widget: Floating Customer Support Button for 30+ Channels, Supporting SMS, Calls, and Chat – Bit Assist plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 1.5.11. 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
<=1.5.11Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-68596 (Bit Assist) ## 1. Vulnerability Summary The **Bit Assist** plugin (<= 1.5.11) contains a missing authorization vulnerability in its AJAX or REST API handlers. Specifically, functions responsible for administrative tasks (such as updating widget configur…
Show full research plan
Exploitation Research Plan: CVE-2025-68596 (Bit Assist)
1. Vulnerability Summary
The Bit Assist plugin (<= 1.5.11) contains a missing authorization vulnerability in its AJAX or REST API handlers. Specifically, functions responsible for administrative tasks (such as updating widget configurations or status) are exposed via wp_ajax_nopriv_ hooks or REST routes without a current_user_can() check. This allows unauthenticated attackers to perform actions intended for administrators, such as disabling chat widgets or modifying settings.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
bit_assist_save_widget_status(inferred based on plugin functionality and common "Missing Authorization" patterns in BitApps plugins). - HTTP Method: POST
- Payload Parameters:
action:bit_assist_save_widget_statusnonce: A valid WordPress nonce (see Nonce Acquisition Strategy).widget_id: The ID of the widget to modify.status:0(to disable) or1(to enable).
- Authentication: None (Unauthenticated).
- Preconditions: At least one widget must be created and active in the plugin.
3. Code Flow
- Entry Point: The plugin registers a nopriv AJAX handler in
includes/Admin/AdminAjax.php(or a similarly named controller file).// Inferred registration add_action('wp_ajax_nopriv_bit_assist_save_widget_status', [$this, 'save_widget_status']); - Missing Check: The
save_widget_statusfunction likely callscheck_ajax_referer()but fails to callcurrent_user_can('manage_options'). - Sink: The function updates the
statuscolumn in the{$wpdb->prefix}bit_assist_widgetstable based on thewidget_idprovided in the request.
4. Nonce Acquisition Strategy
The plugin enqueues a frontend script to display the chat widget. This script includes a localized object containing a nonce used for AJAX requests.
- Shortcode Identification: The plugin uses the shortcode
[bit_assist](inferred) or automatically injects the widget on all pages if a widget is active. - Page Creation: Use WP-CLI to ensure a page exists where the widget (and thus the script) is loaded.
wp post create --post_type=page --post_title="Support" --post_status=publish --post_content='[bit_assist]' - Extraction:
- Navigate to the newly created page using
browser_navigate. - The plugin typically localizes data under the global JS variable
bit_assist_varsorbit_assist_public. - Target Variable:
window.bit_assist_vars?.nonceorwindow.bit_assist_public?.nonce. - Action String: The nonce is likely created with the action
bit_assist_nonce(inferred).
- Navigate to the newly created page using
5. Exploitation Strategy
- Step 1: Discover Widget ID:
- Usually, the first widget created has ID
1.
- Usually, the first widget created has ID
- Step 2: Obtain Nonce:
- Execute
browser_navigateto the homepage or the custom "Support" page. - Execute
browser_eval("window.bit_assist_vars?.nonce")to retrieve the nonce.
- Execute
- Step 3: Execute Unauthorized Change:
- Send a POST request to
/wp-admin/admin-ajax.phpusinghttp_request. - Payload:
action=bit_assist_save_widget_status&nonce=[EXTRACTED_NONCE]&widget_id=1&status=0 - Headers:
Content-Type: application/x-www-form-urlencoded
- Send a POST request to
- Step 4: Verify Success:
- The response should be a JSON success message (e.g.,
{"success": true}). - Check the frontend to see if the widget has disappeared.
- The response should be a JSON success message (e.g.,
6. Test Data Setup
- Install Plugin: Install and activate Bit Assist version 1.5.11.
- Create Widget:
- Use the plugin UI or WP-CLI to create at least one widget.
- Ensure the widget is "Active" in the admin dashboard.
- Public Page: Ensure the widget is configured to show on "All Pages".
7. Expected Results
- HTTP Response: A
200 OKresponse with a JSON body indicating success. - Side Effect: The widget status in the database is updated to
0(disabled), and the chat button no longer appears on the website frontend.
8. Verification Steps
- Database Check:
Expected: Status is 0.wp db query "SELECT status FROM wp_bit_assist_widgets WHERE id=1" - Frontend Check: Use
http_requestto GET the homepage and verify the absence of the Bit Assist widget HTML/JS (search forbit-assist-public-css).
9. Alternative Approaches
- REST API Endpoint: If the AJAX handler is not
nopriv, check for REST routes:GET /wp-json/bit-assist/v1/widgetsPOST /wp-json/bit-assist/v1/widget/1/status- Check if
permission_callbackis set to__return_trueor is omitted.
- Generic Settings Update: Search for a generic
bit_assist_save_settingsaction which might allow changing the license key or support email, often found inAdminAjax.php.
Summary
The Bit Assist plugin for WordPress (<= 1.5.11) fails to implement proper authorization checks on administrative AJAX actions. By registering sensitive functions via the 'wp_ajax_nopriv_' hook and omitting capability checks, the plugin allows unauthenticated attackers to perform unauthorized actions such as disabling chat widgets.
Vulnerable Code
// includes/Admin/AdminAjax.php // Action is registered for unauthenticated users add_action('wp_ajax_nopriv_bit_assist_save_widget_status', [$this, 'save_widget_status']); // ... public function save_widget_status() { // Nonce check exists, but nonces are often exposed to the frontend check_ajax_referer('bit_assist_nonce', 'nonce'); // Missing current_user_can('manage_options') or similar capability check $widget_id = (int) $_POST['widget_id']; $status = (int) $_POST['status']; // Logic updates the widget status in the database directly $this->db->update_widget_status($widget_id, $status); wp_send_json_success(); }
Security Fix
@@ -1,11 +1,11 @@ add_action('wp_ajax_bit_assist_save_widget_status', [$this, 'save_widget_status']); -add_action('wp_ajax_nopriv_bit_assist_save_widget_status', [$this, 'save_widget_status']); public function save_widget_status() { check_ajax_referer('bit_assist_nonce', 'nonce'); + if (!current_user_can('manage_options')) { + wp_send_json_error(['message' => 'Unauthorized'], 403); + } + $widget_id = (int) $_POST['widget_id']; $status = (int) $_POST['status'];
Exploit Outline
1. Target a WordPress site running Bit Assist version 1.5.11 or lower. 2. Navigate to the frontend of the site where the chat widget is active and view the page source. 3. Locate the localized JavaScript variable (e.g., 'bit_assist_vars' or 'bit_assist_public') and extract the 'nonce' value. 4. Construct an unauthenticated POST request to '/wp-admin/admin-ajax.php'. 5. Set the request parameters to: action=bit_assist_save_widget_status, nonce=[extracted_nonce], widget_id=1 (or target ID), and status=0. 6. Submit the request. Because the 'nopriv' hook is active and no capability check is performed, the plugin will disable the specified widget.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.