CVE-2025-67473

CWW Companion <= 1.3.2 - Cross-Site Request Forgery

mediumCross-Site Request Forgery (CSRF)
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.3.3
Patched in
5d
Time to patch

Description

The CWW Companion plugin for WordPress is vulnerable to Cross-Site Request Forgery in all versions up to, and including, 1.3.2. This is due to missing or incorrect nonce validation on a function. This makes it possible for unauthenticated attackers to perform an unauthorized action granted they can trick a site administrator into performing an action such as clicking on a link.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:L/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=1.3.2
PublishedDecember 15, 2025
Last updatedDecember 19, 2025
Affected plugincww-companion

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to identify and exploit the Cross-Site Request Forgery (CSRF) vulnerability in the **CWW Companion** plugin (CVE-2025-67473). ## 1. Vulnerability Summary The **CWW Companion** plugin (up to version 1.3.2) fails to implement proper nonce validation (via `check_a…

Show full research plan

This research plan outlines the steps to identify and exploit the Cross-Site Request Forgery (CSRF) vulnerability in the CWW Companion plugin (CVE-2025-67473).

1. Vulnerability Summary

The CWW Companion plugin (up to version 1.3.2) fails to implement proper nonce validation (via check_admin_referer or check_ajax_referer) on a state-changing function, likely related to plugin settings or configuration. This allows an attacker to perform administrative actions (such as updating plugin options) by tricking a logged-in administrator into visiting a malicious webpage that submits a cross-origin request to the WordPress site.

2. Attack Vector Analysis

  • Vulnerable Endpoint: /wp-admin/admin-post.php or /wp-admin/admin-ajax.php.
  • Action Hook: Likely admin_post_cww_companion_save_settings (inferred) or a similar admin_post_* / wp_ajax_* hook.
  • Payload Parameter: Depends on the specific function; usually includes settings keys and values to be saved in the database.
  • Authentication: Requires a logged-in Administrator to trigger the request (standard CSRF scenario).
  • Preconditions: The victim must have an active session and be tricked into a UI action (e.g., clicking a link or loading a hidden auto-submitting form).

3. Code Flow (Inferred)

  1. The plugin registers an action handler during initialization (e.g., in admin_init or the main plugin file).
  2. Hook Registration: add_action( 'admin_post_cww_companion_save_settings', 'cww_companion_save_settings_callback' ); (inferred).
  3. Vulnerable Function: The callback function processes $_POST data.
  4. Missing Check: The function checks for user capabilities (e.g., current_user_can( 'manage_options' )) but omits check_admin_referer( 'action_string', 'nonce_name' ).
  5. State Change: The function calls update_option() or update_user_meta() based on user-supplied parameters.

4. Nonce Acquisition Strategy

The CVE description indicates the vulnerability is due to missing or incorrect nonce validation.

  • If the validation is missing, no nonce is required in the exploit payload.
  • If the validation is incorrect (e.g., the check is present but ignores the result or uses a wrong action string), any value or a null value might work.
  • Verification: The PoC agent should first attempt the exploit without a nonce. If it fails with a 403 or a "-1" response specifically mentioning security/nonces, the agent should search the source code for the expected nonce action string.

5. Exploitation Strategy

The goal is to change a plugin setting via a CSRF-simulated POST request.

Step 1: Locate the Sink

Use the following commands to find the vulnerable action:

# Search for state-changing hooks
grep -rn "add_action" . | grep -E "admin_post|wp_ajax"

# Search for functions updating options without nonce checks
grep -rn "update_option" . -B 5 | grep -v "nonce"

Step 2: Identify Parameters

Once the function (e.g., cww_companion_save_options) is found, identify the $_POST keys it expects.

Step 3: Execute the Exploit

Using the http_request tool, simulate an admin-authenticated request (CSRF):

  • URL: http://localhost:8080/wp-admin/admin-post.php (or admin-ajax.php)
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body: action=VULNERABLE_ACTION_NAME&setting_key=malicious_value&...

6. Test Data Setup

  1. Plugin State: Ensure CWW Companion v1.3.2 is installed and activated.
  2. Admin User: Use the existing admin user for cookie context.
  3. Target Option: Identify a non-destructive option to modify, such as a "License Key" field or "General Settings" description field within the plugin's menu.

7. Expected Results

  • Response: A 302 Redirect back to the settings page (common for admin-post.php) or a JSON success response (for admin-ajax.php).
  • Database Change: The value of the targeted option in the wp_options table should be updated to the attacker's value.

8. Verification Steps

After sending the http_request, verify the change using WP-CLI:

# Replace 'cww_companion_option_name' with the actual option key found during research
wp option get cww_companion_option_name

If the output matches the payload value, the CSRF is confirmed.

9. Alternative Approaches

If the admin_post route is not found, check for:

  • Settings API Registration: Look for register_setting calls. If the plugin uses the standard Settings API but the form template omits settings_fields(), it might be vulnerable to CSRF on the options.php endpoint.
  • AJAX Handlers: Check wp_ajax_ hooks for functions that perform sensitive tasks (e.g., deleting data) without check_ajax_referer.
Research Findings
Static analysis — not yet PoC-verified

Summary

The CWW Companion plugin for WordPress is vulnerable to Cross-Site Request Forgery (CSRF) in versions up to 1.3.2 due to missing nonce validation on administrative actions. This allows attackers to trick an authenticated administrator into performing unauthorized actions, such as updating plugin settings, by inducing them to visit a malicious webpage.

Vulnerable Code

// Inferred from research plan code flow
// Likely located in an initialization file or settings handler

add_action( 'admin_post_cww_companion_save_settings', 'cww_companion_save_settings_callback' );

function cww_companion_save_settings_callback() {
    // Check for user capabilities, but missing nonce validation (e.g., check_admin_referer)
    if ( current_user_can( 'manage_options' ) ) {
        if ( isset( $_POST['some_plugin_option'] ) ) {
            update_option( 'cww_companion_option_name', sanitize_text_field( $_POST['some_plugin_option'] ) );
        }
        wp_redirect( admin_url( 'admin.php?page=cww-companion' ) );
        exit;
    }
}

Security Fix

--- a/cww-companion.php
+++ b/cww-companion.php
@@ -10,6 +10,10 @@
 
 function cww_companion_save_settings_callback() {
     if ( current_user_can( 'manage_options' ) ) {
+        // Add nonce verification to prevent CSRF
+        if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( $_POST['_wpnonce'], 'cww_companion_save_settings_action' ) ) {
+            wp_die( 'Security check failed' );
+        }
+
         if ( isset( $_POST['some_plugin_option'] ) ) {
             update_option( 'cww_companion_option_name', sanitize_text_field( $_POST['some_plugin_option'] ) );
         }

Exploit Outline

The exploit targets the administrative settings handler through a Cross-Site Request Forgery (CSRF). 1. **Endpoint**: The attacker targets the WordPress admin POST endpoint at `/wp-admin/admin-post.php`. 2. **Payload**: A crafted POST request is prepared containing the `action` parameter (e.g., `cww_companion_save_settings`) and the desired configuration parameters to be modified in the database (e.g., `some_plugin_option=attacker_value`). 3. **Authentication**: The attacker requires a logged-in site administrator to trigger the request. No specific authentication is needed for the attacker themselves. 4. **Mechanism**: The attacker hosts a malicious HTML page with an auto-submitting form or a deceptive link. When the administrator visits this page while logged into their WordPress site, the browser sends the cross-origin POST request. Because the plugin does not verify a nonce (using `check_admin_referer` or `wp_verify_nonce`), the server accepts the request as legitimate and updates the plugin's options.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.