CVE-2025-68021

ConveyThis <= 270.4 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
270.5
Patched in
143d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=270.4
PublishedJanuary 27, 2026
Last updatedJune 18, 2026
Affected pluginconveythis-translate

Source Code

WordPress.org SVN
Patched

Patched version not available.

Research Plan
Unverified

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_init handlers that perform sensitive operations (e.g., updating API keys, changing translation settings, or altering UI configurations) without verifying the user's capabilities (via current_user_can()) or, in some cases, without verifying a nonce. Since some of these handlers may be hooked to wp_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_* or wp_ajax_nopriv_conveythis_save_settings (inferred action names based on plugin functionality).
  • Alternative Endpoint: If the vulnerability is in an admin_init hook, the target may be any request to a page that triggers admin_init, including admin-ajax.php or wp-admin/index.php.
  • Preconditions: The plugin must be installed and active.
  • Authentication: None (Unauthenticated).

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php.
  2. Hook Registration: The plugin registers a handler:
    add_action( 'wp_ajax_nopriv_conveythis_save_settings', array( $this, 'ajax_save_settings' ) ); (inferred).
  3. Vulnerable Function: The callback function (e.g., ajax_save_settings) is executed.
  4. Authorization Failure: The function lacks a if ( ! current_user_can( 'manage_options' ) ) check.
  5. Sink: The function processes $_POST data and calls update_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.

  1. Identify Shortcode: ConveyThis typically uses a language switcher widget or shortcode.
    • Search: grep -rn "add_shortcode" .
    • Common Shortcode: [conveythis] (inferred).
  2. Page Creation: Create a post containing the shortcode:
    wp post create --post_type=page --post_status=publish --post_title="Translate" --post_content='[conveythis]'
  3. Navigate and Extract:
    • Use browser_navigate to visit the new page.
    • Use browser_eval to search for localized data.
    • Localization Keys to Check: conveythis_ajax, convey_this_data, or ConveyThisSettings.
    • JS Command: browser_eval("window.conveythis_ajax?.nonce || window.convey_this_data?.nonce") (inferred).

5. Exploitation Strategy

Once the entry point and nonce (if any) are identified, use the http_request tool.

Example Attempt (API Key Hijacking):

  1. Action: conveythis_save_settings (Verify via grep -r "wp_ajax_nopriv")
  2. Method: POST
  3. URL: http://localhost:8080/wp-admin/admin-ajax.php
  4. Content-Type: application/x-www-form-urlencoded
  5. Payload:
    action=conveythis_save_settings&nonce=[NONCE]&api_key=MALICIOUS_API_KEY&target_languages[0]=fr&target_languages[1]=es
    
    (Note: Parameters names like api_key or conveythis_settings must be confirmed by auditing the handler function.)

6. Test Data Setup

  1. Install and activate the plugin (version <= 269.1).
  2. Navigate to the settings page and save a legitimate API key to establish a baseline state.
  3. Verify the current option value using WP-CLI:
    wp option get conveythis_settings

7. Expected Results

  • The admin-ajax.php request should return a 200 OK response, 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:

  1. Check Options: wp option get conveythis_settings
  2. Compare: Verify that the api_key or other settings match the MALICIOUS_API_KEY sent in the payload.
  3. 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_nopriv hooks are found, search for add_action( 'admin_init', ... ) calls. Check if the callback handles POST requests without checking is_admin() or capabilities.
    • Example: grep -rn "admin_init" . -> Check if it processes $_POST['conveythis_data'].
  • REST API: Check if the plugin registers REST routes via register_rest_route and fails to define a permission_callback.
    • Search: grep -rn "register_rest_route" . -> Look for 'permission_callback' => '__return_true' or missing callback.
Research Findings
Static analysis — not yet PoC-verified

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

--- a/conveythis-translate/includes/admin/class-conveythis-admin.php
+++ b/conveythis-translate/includes/admin/class-conveythis-admin.php
@@ -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.