CVE-2026-12103

Wallet for WooCommerce <= 1.6.4 - Missing Authorization to Authenticated (Subscriber+) User/Email Enumeration via terawallet_export_user_search AJAX Action

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.6.5
Patched in
1d
Time to patch

Description

The Wallet for WooCommerce plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 1.6.4. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with subscriber-level access and above, to enumerate the login name, email address, and user ID of all WordPress accounts — including administrators — by submitting arbitrary search terms to the AJAX handler. The required 'search-user' nonce is localized into the wallet_param object on the standard WooCommerce My Account page, which is accessible to any authenticated user, making it trivially obtainable by a Subscriber.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.6.4
PublishedJuly 10, 2026
Last updatedJuly 11, 2026
Affected pluginwoo-wallet

What Changed in the Fix

Changes introduced in v1.6.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This exploitation research plan targets **CVE-2026-12103**, a missing authorization vulnerability in the **Wallet for WooCommerce (TeraWallet)** plugin. The goal is to demonstrate how an authenticated user with Subscriber-level permissions can enumerate all registered users' login names and email ad…

Show full research plan

This exploitation research plan targets CVE-2026-12103, a missing authorization vulnerability in the Wallet for WooCommerce (TeraWallet) plugin. The goal is to demonstrate how an authenticated user with Subscriber-level permissions can enumerate all registered users' login names and email addresses.


1. Vulnerability Summary

The vulnerability exists in the terawallet_export_user_search function within includes/class-woo-wallet-ajax.php. While the function performs a nonce check and a capability check, the capability check relies on get_wallet_user_capability(). In affected versions, this capability defaults to one held by Subscriber-level users, or the function fails to enforce administrative restrictions required for global user enumeration. Consequently, any authenticated user can query the WordPress user database via the AJAX endpoint.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: terawallet_export_user_search
  • HTTP Method: POST
  • Parameters:
    • action: terawallet_export_user_search (Required)
    • security: The search-user nonce (Required)
    • term: The search string for enumeration (e.g., a or @)
  • Authentication: Authenticated (Subscriber or higher)
  • Preconditions: The attacker must obtain a valid nonce, which is localized for all authenticated users on the "My Account" page.

3. Code Flow

  1. Entry Point: The AJAX request triggers wp_ajax_terawallet_export_user_search, which calls Woo_Wallet_Ajax::terawallet_export_user_search().
  2. Nonce Verification: check_ajax_referer( 'search-user', 'security' ) (Line 186) validates the transaction-specific token.
  3. Authorization Check: get_wallet_user_capability() (Line 188) is invoked. The vulnerability stems from this function returning true or a low-privilege capability (like read) for Subscriber users.
  4. Data Sink: get_users() (Line 195) is called with the user-provided term mapped to the search parameter with wildcards (*term*). It specifically searches user_login, user_nicename, and user_email.
  5. Data Exposure: The results are looped (Lines 203-210) and returned via wp_send_json(), leaking the user_login and user_email.

4. Nonce Acquisition Strategy

The search-user nonce is required to bypass the check_ajax_referer check. The plugin localizes this nonce into the wallet_param JavaScript object on pages where wallet functionality is initialized, specifically the WooCommerce "My Account" page.

Acquisition Steps:

  1. Log in as a Subscriber user.
  2. Navigate to the /my-account/ page.
  3. The nonce is embedded in the HTML source within a script block.
  4. Use the browser_eval tool to extract the nonce:
    browser_eval("window.wallet_param?.search_user_nonce")
    
    (Note: Based on standard TeraWallet localization patterns, the key is expected to be search_user_nonce or similar within the wallet_param object).

5. Exploitation Strategy

The exploitation involves sending a crafted POST request to the AJAX endpoint using the obtained nonce.

Step-by-Step Plan:

  1. Login: Authenticate as a Subscriber user and capture the session cookies.
  2. Retrieve Nonce: Navigate to /my-account/ and extract the security token from wallet_param.
  3. Perform Enumeration: Use the http_request tool to send a search query.
    • URL: http://[target]/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=terawallet_export_user_search&security=[NONCE]&term=@
      (Using @ is effective for capturing all email addresses; a or e are effective for capturing common logins).

6. Test Data Setup

To verify the vulnerability, the environment should contain:

  1. Administrator Account: (e.g., admin_user / admin@example.com).
  2. Victim Account: A second user to prove enumeration (e.g., victim_user / victim@example.com).
  3. Attacker Account: A Subscriber-level user (e.g., attacker / attacker@example.com).
  4. Plugin Config: Default "Wallet for WooCommerce" installation.
  5. Page Setup: Ensure the WooCommerce "My Account" page is published and accessible to the attacker user.

7. Expected Results

A successful exploit will return a 200 OK status with a JSON array. Each element in the array will contain:

  • label: A string formatted as Username (email@example.com).
  • value: The integer User ID.

Example Response:

[
  {"label": "admin (admin@example.com)", "value": 1},
  {"label": "victim_user (victim@example.com)", "value": 2},
  {"label": "attacker (attacker@example.com)", "value": 3}
]

8. Verification Steps

After the exploit, verify the accuracy of the leaked data using WP-CLI:

  1. List Users: Run wp user list --fields=ID,user_login,user_email and compare the output to the JSON returned by the exploit.
  2. Confirm Capability: Check the return value of the capability helper for a Subscriber:
    wp eval "wp_set_current_user( [ATTACKER_ID] ); echo get_wallet_user_capability();"
    

9. Alternative Approaches

If wallet_param is not found on the My Account page:

  • Shortcode Discovery: Scan the source code for add_shortcode (e.g., [terawallet_dashboard]).
  • Page Creation: Create a private page with the discovered shortcode:
    wp post create --post_type=page --post_status=publish --post_content='[terawallet_dashboard]' --post_author=[ATTACKER_ID]
    
  • Re-attempt Extraction: Navigate to the new page and attempt to extract wallet_param again, as the shortcode often triggers the script and nonce localization.

Check if your site is affected.

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