CVE-2026-42654

Wallet System for WooCommerce – Digital Wallet, Buy Now Pay Later (BNPL), Instant Cashback, Referral program, Partial & Subscription Payments <= 2.7.5 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
2.7.6
Patched in
6d
Time to patch

Description

The Wallet System for WooCommerce – Digital Wallet, Buy Now Pay Later (BNPL), Instant Cashback, Referral program, Partial & Subscription Payments plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.7.5. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.7.5
PublishedApril 29, 2026
Last updatedMay 4, 2026

What Changed in the Fix

Changes introduced in v2.7.6

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan targets a **Missing Authorization** vulnerability in the **Wallet System for WooCommerce** plugin (<= 2.7.5). The vulnerability allows authenticated users with Subscriber-level access to perform unauthorized actions, specifically dismissing administrative notices site-wide due to …

Show full research plan

This research plan targets a Missing Authorization vulnerability in the Wallet System for WooCommerce plugin (<= 2.7.5). The vulnerability allows authenticated users with Subscriber-level access to perform unauthorized actions, specifically dismissing administrative notices site-wide due to a missing capability check in an AJAX handler.

1. Vulnerability Summary

  • ID: CVE-2026-42654
  • Vulnerability Type: Missing Authorization (CWE-862)
  • Vulnerable Function: wps_wsfw_dismiss_notice_banner (Action) / Associated AJAX handler.
  • Affected Code: The AJAX registration for wps_wsfw_dismiss_notice_banner is likely handled in includes/class-wallet-system-ajaxhandler.php or admin/class-wallet-system-for-woocommerce-admin.php.
  • Reason: The plugin registers an AJAX action for authenticated users but only verifies a nonce (wp_rest) without checking if the user has administrative capabilities (e.g., manage_options). Since the script and nonce are enqueued for all users accessing the dashboard (including Subscribers), any logged-in user can trigger the action.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: wps_wsfw_dismiss_notice_banner
  • HTTP Method: POST
  • Authentication: Required (Subscriber level or higher)
  • Payload Parameters:
    • action: wps_wsfw_dismiss_notice_banner
    • wps_nonce: A valid wp_rest nonce (localized for the current user).
  • Preconditions: The plugin must be active. A Subscriber user must be created.

3. Code Flow

  1. Enqueuing: The method wsfw_admin_enqueue_scripts in admin/class-wallet-system-for-woocommerce-admin.php registers and enqueues the script admin-notice.
  2. Localization: Inside wsfw_admin_enqueue_scripts, the plugin localizes the object wps_wsfw_branner_notice, which contains a nonce generated via wp_create_nonce( 'wp_rest' ).
  3. Client-Side: The file admin/js/wps-wsfw-wallet-card-notices.js attaches a click listener to #dismiss-banner. When clicked, it sends a POST request to admin-ajax.php with the wps_nonce.
  4. Server-Side Handler: The handler for wps_wsfw_dismiss_notice_banner (likely in class-wallet-system-ajaxhandler.php) checks the nonce using wp_verify_nonce but fails to check current_user_can( 'manage_options' ).
  5. Sink: The handler typically updates a global option (e.g., wps_wsfw_notice_dismissed) or user meta, affecting the display of notices for all administrators.

4. Nonce Acquisition Strategy

The nonce is user-bound and action-bound to wp_rest. It is exposed to any logged-in user who can access the WordPress admin area (Subscribers can access /wp-admin/profile.php).

  1. Login: Authenticate as a Subscriber.
  2. Navigate: Use browser_navigate to go to http://localhost:8888/wp-admin/profile.php.
  3. Extract: Use browser_eval to extract the localized nonce from the global JavaScript object.
    • JavaScript Variable: window.wps_wsfw_branner_notice
    • Key: wps_wsfw_nonce
    • Command: browser_eval("window.wps_wsfw_branner_notice.wps_wsfw_nonce")

5. Exploitation Strategy

  1. Step 1: Setup: Ensure the plugin is active and a Subscriber user exists.
  2. Step 2: Obtain Nonce: Log in as a Subscriber and extract the wps_wsfw_nonce from the profile page.
  3. Step 3: Execute Unauthorized Action: Send a POST request to admin-ajax.php to dismiss the admin notice.

Request Details:

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8888
Content-Type: application/x-www-form-urlencoded
Cookie: [Subscriber Cookies]

action=wps_wsfw_dismiss_notice_banner&wps_nonce=[EXTRACTED_NONCE]

6. Test Data Setup

  1. Install Plugin: Ensure version 2.7.5 is installed.
  2. Create User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password
    
  3. Verify Initial State: Check if the dismissal option is NOT set (or set to 'no').
    wp option get wps_wsfw_notice_dismissed
    

7. Expected Results

  • Response: The server should return a 1, success, or a JSON response indicating the notice has been dismissed.
  • Integrity Impact: The administrative notice (banner) will no longer appear for any user, including administrators, because the underlying option has been modified by a low-privileged user.

8. Verification Steps

  1. Check Option: After the request, verify that the option used to track notice dismissal has been updated.
    wp option get wps_wsfw_notice_dismissed
    
    (Note: If the option name is different, use wp option list --search="wps_wsfw" to find the correct flag).
  2. Login as Admin: Log in as an administrator and navigate to the dashboard. Observe that the Wallet System notice banner is gone.

9. Alternative Approaches

If wps_wsfw_dismiss_notice_banner is not the specific "unauthorized action" intended by the CVSS 4.3 rating, look for other AJAX actions registered in includes/class-wallet-system-ajaxhandler.php (if accessible) or via grep:

grep -r "wp_ajax_" . | grep -v "nopriv"

Common vulnerable candidates in this plugin include:

  • wps_wsfw_update_user_wallet: If this lacks a capability check, a Subscriber could modify their own (or others') wallet balances.
  • wps_wsfw_wallet_recharge_action: Unauthorized wallet recharges.

However, the presence of the localized wp_rest nonce in admin-notice strongly confirms wps_wsfw_dismiss_notice_banner as the primary intended attack vector for this vulnerability ID.

Check if your site is affected.

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