ThriveDesk <= 2.1.7 - Missing Authorization to Authenticated (Subscriber+) Cache Deletion
Description
The ThriveDesk – Live Chat, AI Chatbot, Helpdesk & Knowledge Base plugin for WordPress is vulnerable to unauthorized cache deletion due to a missing capability check on the 'thrivedesk_clear_cache' AJAX action in all versions up to, and including, 2.1.7. This makes it possible for authenticated attackers, with Subscriber-level access and above, to clear the plugin's cache.
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 v2.2.0
Source Code
WordPress.org SVNThis research plan outlines the steps required to demonstrate the missing authorization vulnerability in the ThriveDesk plugin, allowing a Subscriber-level user to clear the plugin's cache. ### 1. Vulnerability Summary The ThriveDesk plugin for WordPress (versions <= 2.1.7) fails to perform a capab…
Show full research plan
This research plan outlines the steps required to demonstrate the missing authorization vulnerability in the ThriveDesk plugin, allowing a Subscriber-level user to clear the plugin's cache.
1. Vulnerability Summary
The ThriveDesk plugin for WordPress (versions <= 2.1.7) fails to perform a capability check (e.g., current_user_can( 'manage_options' )) in the handler for the thrivedesk_clear_cache AJAX action. While the plugin may implement nonce verification, the nonce is often exposed to all authenticated users in the WordPress admin dashboard (e.g., via script localization on the profile.php page). Consequently, any authenticated user with at least Subscriber-level permissions can trigger the cache deletion functionality.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
thrivedesk_clear_cache - Method: POST
- Parameters:
action:thrivedesk_clear_cache_nonceornonce(inferred): The security token for the request.
- Required Authentication: Subscriber-level account (PR:L).
- Preconditions: The plugin must be active and the Subscriber user must be able to access the WordPress backend (standard for WordPress sites unless explicitly disabled).
3. Code Flow (Inferred)
- Registration: The plugin registers the AJAX action during initialization:
add_action( 'wp_ajax_thrivedesk_clear_cache', 'thrivedesk_clear_cache_handler' ); - Trigger: An authenticated user sends a POST request to
admin-ajax.phpwithaction=thrivedesk_clear_cache. - Vulnerable Handler: The handler function (likely
thrivedesk_clear_cache_handler) is called. It may check a nonce usingcheck_ajax_refererorwp_verify_nonce, but it fails to check if the user has administrative privileges. - Sink: The handler calls the internal clearing function (e.g., clearing transients or database options) and returns a success response.
4. Nonce Acquisition Strategy
Because the source files provided are primarily CSS and bundled JS, the exact nonce variable name must be identified dynamically. Most WordPress plugins localize their data into a global window object.
- Identify the variable: Search for where ThriveDesk localizes its script data.
- Command:
grep -rn "wp_localize_script" .in the plugin directory. - Expected identifiers: Look for
td_nonce,thrivedesk, orthrivedesk_admin_options.
- Command:
- Acquisition Flow:
- Log in as a Subscriber.
- Navigate to
/wp-admin/profile.php. - Use
browser_evalto find the ThriveDesk object and its nonce. - Probable JS Path:
window.thrivedesk?.nonceorwindow.td_admin?.nonce.
5. Exploitation Strategy
- Preparation:
- Log in as a Subscriber using the
http_requestorbrowser_navigatetool.
- Log in as a Subscriber using the
- Nonce Extraction:
- Navigate to the WordPress dashboard (Subscriber view).
- Execute JS to find the nonce:
// Example search for the nonce in the window object Object.keys(window).find(key => key.includes('thrivedesk'));
- Execution:
- Construct a POST request to
admin-ajax.php. - URL:
http://[target]/wp-admin/admin-ajax.php - Body (URL-encoded):
action=thrivedesk_clear_cache_ajax_nonce=[EXTRACTED_NONCE](Note: The parameter name might benonce,_nonce, ortd_nonce).
- Construct a POST request to
- Capture Response:
- Verify the HTTP status is 200.
- Look for a success indicator in the body:
{"success":true}or1.
6. Test Data Setup
- Plugin Installation: Install and activate the ThriveDesk plugin (version 2.1.7).
- User Creation: Create a user with the
subscriberrole.wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
- Cache Generation: Ensure some plugin data is cached (e.g., by visiting ThriveDesk settings as an admin or interacting with the plugin if it caches API responses).
7. Expected Results
- The Subscriber's request to
thrivedesk_clear_cacheshould be accepted. - The server response should indicate success (e.g., JSON
{"success":true}). - The plugin's cache/transients should be removed.
8. Verification Steps
- Manual Check: Before running the exploit, check if specific ThriveDesk transients exist in the database.
wp transient list --search="thrivedesk*"
- Post-Exploit Check: After the Subscriber request, verify the transients are gone.
wp transient list --search="thrivedesk*"
- Response Analysis: Confirm the response was not a 403 Forbidden or a
0(which typically indicates a failed AJAX registration or auth failure in WordPress).
9. Alternative Approaches
- REST API: Check if a similar endpoint exists via the REST API (referencing
assets/js/wp-scripts/thrivedesk-autonami-tab.jswhich useswp-api-fetch).- Check for routes like
thrivedesk/v1/cache/clear.
- Check for routes like
- Nonce-less Attempt: If the
grepsearch forcheck_ajax_refererin the plugin's PHP files returns no results, try the request without a nonce parameter to confirm if verification is missing entirely.
Summary
The ThriveDesk plugin for WordPress fails to perform a capability check in its 'thrivedesk_clear_cache' AJAX handler in versions up to 2.1.7. This allows any authenticated user, including those with low-level Subscriber permissions, to clear the plugin's internal cache by sending a crafted AJAX request.
Vulnerable Code
// File path: thrivedesk.php (or similar main plugin/AJAX handler file) // Line numbers inferred from common WordPress AJAX registration patterns add_action( 'wp_ajax_thrivedesk_clear_cache', 'thrivedesk_clear_cache_handler' ); function thrivedesk_clear_cache_handler() { // The vulnerability exists here because there is no check for user capabilities // like current_user_can( 'manage_options' ) before performing the action. thrivedesk_options_cache_clear(); wp_send_json_success(); }
Security Fix
@@ -100,6 +100,10 @@ function thrivedesk_clear_cache_handler() { + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 ); + } + + check_ajax_referer( 'thrivedesk_nonce', 'nonce' ); + thrivedesk_options_cache_clear(); wp_send_json_success(); }
Exploit Outline
To exploit this vulnerability, an attacker first authenticates as a Subscriber-level user and navigates to the WordPress admin dashboard (e.g., /wp-admin/profile.php). From the page source or the global JavaScript 'window' object, the attacker extracts a valid nonce associated with ThriveDesk (often localized via wp_localize_script). The attacker then sends an AJAX POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to 'thrivedesk_clear_cache' and the extracted nonce. Because the server-side handler lacks a 'current_user_can' check, the plugin clears its cache and returns a success response to the unauthorized user.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.