CVE-2026-27541

Wholesale Suite <= 2.2.6 - Authenticated (Shop Manager) Privilege Escalation

highImproper Privilege Management
7.2
CVSS Score
7.2
CVSS Score
high
Severity
2.2.7
Patched in
15d
Time to patch

Description

The Wholesale Suite – B2B, Dynamic Pricing & WooCommerce Wholesale Prices plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 2.2.6.This makes it possible for authenticated attackers, with Shop Manager-level access and above, to elevate their privileges to that of an administrator.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.2.6
PublishedFebruary 20, 2026
Last updatedMarch 6, 2026

What Changed in the Fix

Changes introduced in v2.2.7

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-27541 - Wholesale Suite Privilege Escalation ## 1. Vulnerability Summary The **Wholesale Suite (woocommerce-wholesale-prices)** plugin for WordPress (versions <= 2.2.6) contains a privilege escalation vulnerability. The core issue resides in the plugin's settings managemen…

Show full research plan

Research Plan: CVE-2026-27541 - Wholesale Suite Privilege Escalation

1. Vulnerability Summary

The Wholesale Suite (woocommerce-wholesale-prices) plugin for WordPress (versions <= 2.2.6) contains a privilege escalation vulnerability. The core issue resides in the plugin's settings management or role management functionality. It allows authenticated users with Shop Manager capabilities (who typically have manage_woocommerce) to perform administrative actions, specifically escalating their own role or modifying site-wide settings (like default_role) due to insufficient capability checks (checking for manage_woocommerce or edit_posts instead of manage_options) in AJAX or REST API handlers.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php (or potentially a REST API endpoint under wp-json/wholesale-suite/v1/).
  • Vulnerable Action: Likely wwp_save_settings, wwp_ajax_save_settings, or wwhp_update_settings (inferred from plugin naming conventions).
  • Payload Parameter: settings or a specific option parameter like default_role.
  • Authentication: Authenticated, Shop Manager level or higher.
  • Preconditions: The plugin must be active, and a Shop Manager account must be available.

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers an AJAX handler using add_action( 'wp_ajax_wwp_save_settings', ... ) (or similar).
  2. Authorization Check: The handler likely uses current_user_can( 'manage_woocommerce' ). While Shop Managers have this, they should not be allowed to modify arbitrary site options or roles.
  3. Nonce Verification: A nonce check is likely present (e.g., check_ajax_referer( 'wwp_settings_nonce', 'nonce' )), but this nonce is exposed to Shop Managers on the plugin's settings page.
  4. Processing: The code iterates through the provided settings array.
  5. Sink: It calls update_option() for each key-value pair without a whitelist of allowed options, or it improperly handles role assignments during user updates.

4. Nonce Acquisition Strategy

To obtain a valid nonce for the Shop Manager user:

  1. Identify Trigger: The plugin settings are typically located at /wp-admin/admin.php?page=wwp-settings.
  2. Access Page: Log in as the Shop Manager and navigate to the settings page.
  3. Extract Nonce: The nonce is likely localized in the page source via wp_localize_script.
    • JS Variable: Based on the manifest and plugin history, check window.wwp_settings_vars or window.wwp_bulk_actions_vars.
    • Key: Look for nonce or wwp_settings_nonce.
  4. Command:
    // Browser Eval
    browser_eval("window.wwp_settings_vars?.nonce || window.wwp_vars?.nonce")
    

5. Exploitation Strategy

The goal is to update the WordPress default_role to administrator and then trigger a registration, or directly update the current user's role if the endpoint supports it.

Step-by-Step Plan:

  1. Login: Authenticate as the Shop Manager user.
  2. Discover Action: Grep the plugin directory for the settings saving action:
    grep -rn "wp_ajax_" . | grep "save"
  3. Obtain Nonce: Navigate to the plugin settings page and extract the nonce using browser_eval.
  4. Execute Privilege Escalation:
    • Method A: Update default_role (if the handler allows arbitrary options):
      • Request: POST /wp-admin/admin-ajax.php
      • Content-Type: application/x-www-form-urlencoded
      • Body: action=wwp_save_settings&nonce=[NONCE]&settings[default_role]=administrator (or similar structure).
    • Method B: Direct Role Update (if the handler supports user modification):
      • Request: POST /wp-admin/admin-ajax.php
      • Body: action=wwp_update_user_role&nonce=[NONCE]&user_id=[CURRENT_ID]&role=administrator

6. Test Data Setup

  1. Install Plugin: Wholesale Suite <= 2.2.6 and WooCommerce.
  2. Create User: A user with the shop_manager role.
  3. Configure Plugin: Ensure the plugin is initialized so settings pages are accessible.
  4. Identify Settings Page: Confirm the slug (usually wwp-settings).

7. Expected Results

  • Response: A successful response (e.g., {"success": true} or 1).
  • Effect: The WordPress option default_role is changed to administrator, OR the Shop Manager user's role is directly changed to administrator in the wp_users/wp_usermeta tables.

8. Verification Steps

  1. Check Option via WP-CLI:
    wp option get default_role (Should return administrator).
  2. Check User Role via WP-CLI:
    wp user get [USERNAME] --field=roles (Should return administrator).
  3. UI Verification: Log in as the former Shop Manager and verify that the "Plugins" and "Settings" menus are now visible (indicating full Admin access).

9. Alternative Approaches

  • REST API: If AJAX is well-protected, check for REST routes:
    grep -rn "register_rest_route" .
    Look for endpoints that update settings and check if the permission_callback only checks for manage_woocommerce.
  • Insecure Deserialization: If the settings are saved as a serialized object, check if the plugin uses unserialize() on the input before saving.
  • Wholesale Role Management: Specifically target the "Wholesale Roles" creation feature. If a Shop Manager can create a role with administrator capabilities, they can then assign it to themselves.
    • Action: wwp_add_wholesale_role
    • Payload: role_name=attacker_role&capabilities[administrator]=1

Check if your site is affected.

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