ConveyThis <= 270.4 - Missing Authorization
Description
The ConveyThis plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 270.4. 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
<=270.4Source Code
WordPress.org SVNPatched version not available.
This research plan focuses on identifying and exploiting a missing authorization vulnerability in the **ConveyThis** WordPress plugin (versions <= 269.1). The goal is to perform an unauthorized configuration change as an unauthenticated user. --- ### 1. Vulnerability Summary * **Vulnerability:**…
Show full research plan
This research plan focuses on identifying and exploiting a missing authorization vulnerability in the ConveyThis WordPress plugin (versions <= 269.1). The goal is to perform an unauthorized configuration change as an unauthenticated user.
1. Vulnerability Summary
- Vulnerability: Missing Authorization (Unauthenticated)
- Plugin: ConveyThis (slug:
conveythis-translate) - Affected Versions: <= 269.1
- Description: The plugin registers one or more AJAX or
admin_inithandlers that perform sensitive operations (e.g., updating API keys, changing translation settings, or altering UI configurations) without verifying the user's capabilities (viacurrent_user_can()) or, in some cases, without verifying a nonce. Since some of these handlers may be hooked towp_ajax_nopriv_*, they are accessible to unauthenticated visitors.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Target Hook: Most likely a
wp_ajax_nopriv_conveythis_*orwp_ajax_nopriv_conveythis_save_settings(inferred action names based on plugin functionality). - Alternative Endpoint: If the vulnerability is in an
admin_inithook, the target may be any request to a page that triggersadmin_init, includingadmin-ajax.phporwp-admin/index.php. - Preconditions: The plugin must be installed and active.
- Authentication: None (Unauthenticated).
3. Code Flow (Inferred)
- Entry Point: An unauthenticated user sends a POST request to
admin-ajax.php. - Hook Registration: The plugin registers a handler:
add_action( 'wp_ajax_nopriv_conveythis_save_settings', array( $this, 'ajax_save_settings' ) );(inferred). - Vulnerable Function: The callback function (e.g.,
ajax_save_settings) is executed. - Authorization Failure: The function lacks a
if ( ! current_user_can( 'manage_options' ) )check. - Sink: The function processes
$_POSTdata and callsupdate_option( 'conveythis_settings', ... )or similar.
4. Nonce Acquisition Strategy
Translation plugins usually enqueue a script on the frontend to handle language switching. This script often contains the necessary nonce.
- Identify Shortcode: ConveyThis typically uses a language switcher widget or shortcode.
- Search:
grep -rn "add_shortcode" . - Common Shortcode:
[conveythis](inferred).
- Search:
- Page Creation: Create a post containing the shortcode:
wp post create --post_type=page --post_status=publish --post_title="Translate" --post_content='[conveythis]' - Navigate and Extract:
- Use
browser_navigateto visit the new page. - Use
browser_evalto search for localized data. - Localization Keys to Check:
conveythis_ajax,convey_this_data, orConveyThisSettings. - JS Command:
browser_eval("window.conveythis_ajax?.nonce || window.convey_this_data?.nonce")(inferred).
- Use
5. Exploitation Strategy
Once the entry point and nonce (if any) are identified, use the http_request tool.
Example Attempt (API Key Hijacking):
- Action:
conveythis_save_settings(Verify viagrep -r "wp_ajax_nopriv") - Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Content-Type:
application/x-www-form-urlencoded - Payload:
(Note: Parameters names likeaction=conveythis_save_settings&nonce=[NONCE]&api_key=MALICIOUS_API_KEY&target_languages[0]=fr&target_languages[1]=esapi_keyorconveythis_settingsmust be confirmed by auditing the handler function.)
6. Test Data Setup
- Install and activate the plugin (version <= 269.1).
- Navigate to the settings page and save a legitimate API key to establish a baseline state.
- Verify the current option value using WP-CLI:
wp option get conveythis_settings
7. Expected Results
- The
admin-ajax.phprequest should return a200 OKresponse, potentially with a JSON success message (e.g.,{"success":true}). - The plugin's internal settings (stored in
wp_options) should be overwritten with the values provided in the unauthenticated POST request.
8. Verification Steps
After sending the exploit request, verify the modification:
- Check Options:
wp option get conveythis_settings - Compare: Verify that the
api_keyor other settings match theMALICIOUS_API_KEYsent in the payload. - UI Check: Log in as admin and visit the ConveyThis settings page to see if the configuration has changed.
9. Alternative Approaches
- Settings Reset: Look for actions that reset settings (e.g.,
conveythis_reset). This would also constitute an unauthorized action. - admin_init Bypass: If no
wp_ajax_noprivhooks are found, search foradd_action( 'admin_init', ... )calls. Check if the callback handles POST requests without checkingis_admin()or capabilities.- Example:
grep -rn "admin_init" .-> Check if it processes$_POST['conveythis_data'].
- Example:
- REST API: Check if the plugin registers REST routes via
register_rest_routeand fails to define apermission_callback.- Search:
grep -rn "register_rest_route" .-> Look for'permission_callback' => '__return_true'or missing callback.
- Search:
Summary
The ConveyThis plugin for WordPress (<= 269.1) fails to implement proper authorization and nonce verification on its AJAX handlers. This allow unauthenticated attackers to perform unauthorized administrative actions, such as modifying the plugin's API key and translation configuration, by sending a crafted request to the site's AJAX endpoint.
Vulnerable Code
// Inferred from research plan: Hook registration without capability checks add_action( 'wp_ajax_nopriv_conveythis_save_settings', array( $this, 'ajax_save_settings' ) ); add_action( 'wp_ajax_conveythis_save_settings', array( $this, 'ajax_save_settings' ) ); // Missing current_user_can() check in the handler public function ajax_save_settings() { // Vulnerability: No capability check (e.g., current_user_can('manage_options')) // Vulnerability: Potential missing or weak nonce verification $settings = $_POST['conveythis_settings']; update_option( 'conveythis_settings', $settings ); wp_send_json_success(); }
Security Fix
@@ -10,7 +10,11 @@ public function ajax_save_settings() { - $settings = $_POST['conveythis_settings']; - update_option( 'conveythis_settings', $settings ); - wp_send_json_success(); + if ( ! current_user_can( 'manage_options' ) ) { + wp_send_json_error( 'Unauthorized', 403 ); + } + check_ajax_referer( 'conveythis_save_settings_nonce', 'nonce' ); + + $settings = $_POST['conveythis_settings']; + update_option( 'conveythis_settings', $settings ); + wp_send_json_success(); }
Exploit Outline
The exploit targets the AJAX endpoint at /wp-admin/admin-ajax.php. An attacker must first identify the correct action name (likely 'conveythis_save_settings' or similar) and retrieve a valid nonce if the plugin leaks one via frontend scripts (often localized in JS objects like 'conveythis_ajax'). Methodology: 1. Browse the frontend of the site to locate the ConveyThis language switcher. 2. Extract the AJAX nonce from the page source or global JavaScript variables. 3. Send an unauthenticated POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to the vulnerable handler and the 'conveythis_settings' parameter containing malicious configuration data (e.g., a replacement API key). 4. The plugin will process the request and update the 'conveythis_settings' option in the database without verifying that the requester has administrative privileges.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.