B2BKing — Ultimate WooCommerce B2B and Wholesale Plugin — Wholesale Prices, Bulk Order Form & More < 5.2.10 - Missing Authorization
Description
The B2BKing — Ultimate WooCommerce B2B and Wholesale Plugin — Wholesale Prices, Bulk Order Form & More plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to 5.2.10. This makes it possible for authenticated attackers, with shop manager-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:NTechnical Details
<5.2.10What Changed in the Fix
Changes introduced in v5.2.10
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-27346 ## 1. Vulnerability Summary The **B2BKing — Ultimate WooCommerce B2B and Wholesale Plugin** (versions < 5.2.10) is vulnerable to **Missing Authorization**. Specifically, several AJAX functions registered in the `B2bkingcore_Admin` class (located in `adm…
Show full research plan
Exploitation Research Plan - CVE-2026-27346
1. Vulnerability Summary
The B2BKing — Ultimate WooCommerce B2B and Wholesale Plugin (versions < 5.2.10) is vulnerable to Missing Authorization. Specifically, several AJAX functions registered in the B2bkingcore_Admin class (located in admin/class-b2bking-admin.php) fail to perform capability checks (e.g., current_user_can('manage_options')). This allow authenticated users with roles such as Shop Manager to perform administrative actions, such as bulk-moving users into different B2B customer groups, which can lead to unauthorized price access or permission escalation within the B2B system.
2. Attack Vector Analysis
- Vulnerable Endpoint:
/wp-admin/admin-ajax.php - AJAX Action:
b2bking_set_users_in_group(derived from the tool's container ID inadminstyle.css) orb2bking_set_users_in_bulk. - HTTP Method: POST
- Authentication: Authenticated, Shop Manager role (or any role that can access the WordPress admin but lacks B2BKing management privileges).
- Parameters:
action:b2bking_set_users_in_groupsecurity: A valid WordPress nonce for the actionb2bking_admin_nonce.users: A single user ID or an array/comma-separated list of user IDs to modify.group: The ID of theb2bking_grouppost type to assign users to.
3. Code Flow
- Registration: In
admin/class-b2bking-admin.php, the plugin registers AJAX handlers during initialization (likely inside theplugins_loadedorinithook, or within theB2bkingcore_Adminconstructor). - Hook:
add_action('wp_ajax_b2bking_set_users_in_group', array($this, 'b2bking_set_users_in_group')). - Execution: When a Shop Manager sends a POST request to
admin-ajax.phpwith the specified action:- The function
b2bking_set_users_in_group()is called. - It calls
check_ajax_referer('b2bking_admin_nonce', 'security')to verify the nonce. - Vulnerability: It fails to call
current_user_can('manage_options'). - It proceeds to iterate through the
usersparameter and updates their user meta (typicallyb2bking_customer_group) to match thegroupparameter.
- The function
4. Nonce Acquisition Strategy
The B2BKing plugin localizes its admin data into a global JavaScript object named b2bking. The nonce is typically assigned to b2bking.security.
Strategy:
- Identification: The
admin/class-b2bking-admin.phpregisters panels for the Product Edit page (woocommerce_product_data_panels). Shop Managers have permission to edit products. - Setup: The PoC agent should navigate to an existing product's edit page.
- Extraction:
- Navigate to
/wp-admin/post.php?post=[PRODUCT_ID]&action=edit. - Use
browser_evalto extract the nonce:window.b2bking?.security || window.b2bking?.nonce - Note: If the Shop Manager cannot access the B2BKing Tools page directly, they can still obtain this nonce because the plugin enqueues its global admin scripts on all product pages to handle the "B2BKing" tab/panel.
- Navigate to
5. Exploitation Strategy
Step-by-Step Plan:
- Login: Authenticate as a Shop Manager.
- Nonce Extraction: Navigate to the product editor and extract
b2bking.security. - Target Identification: Identify a
b2bking_groupID (can be listed viawp post list --post_type=b2bking_group) and a target User ID (e.g., the Shop Manager's own ID to gain discounts). - Execution: Send a POST request to
admin-ajax.php.
Request Details:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method: POST
- Content-Type:
application/x-www-form-urlencoded - Body:
action=b2bking_set_users_in_group&security=[NONCE]&users=[USER_ID]&group=[GROUP_ID]
6. Test Data Setup
- Create Group:
wp post create --post_type=b2bking_group --post_title="VIP Wholesale" --post_status=publish- Note the ID of this group.
- Create Shop Manager:
wp user create shopmanager shopmanager@example.com --role=shop_manager --user_pass=password - Create Target User:
wp user create victim victim@example.com --role=subscriber- Note the ID of this user.
- Verify Plugin State: Ensure B2BKing is active and a product exists for the Shop Manager to visit.
7. Expected Results
- Success Response: The server returns a success message (often
1, or a JSON object like{"success": true}). - Effect: The user meta for the target user is updated.
8. Verification Steps
After the HTTP request, use WP-CLI to verify the metadata change:
# Check if the victim user is now assigned to the group
wp user meta get [VICTIM_USER_ID] b2bking_customer_group
The output should match the GROUP_ID used in the exploit.
9. Alternative Approaches
If b2bking_set_users_in_group is not the exact action name:
- Examine CSS: Check
admin/assets/css/adminstyle.cssfor other tool IDs (e.g.,b2bking_set_category_in_bulk). - Scan AJAX Actions: Look for any
wp_ajax_registration inadmin/class-b2bking-admin.phpthat involves "save", "update", or "set". - Check for Export Vulnerability: Try
action=b2bking_download_products(referenced by IDb2bking_download_products_buttonin CSS) to see if a Shop Manager can trigger a CSV export of wholesale data they shouldn't see.
Summary
The B2BKing plugin for WordPress is vulnerable to a missing authorization check on its administrative AJAX functions. This allows authenticated attackers with Shop Manager privileges to perform unauthorized actions, such as bulk-moving users into B2B customer groups, which can lead to unauthorized access to wholesale pricing or permissions.
Vulnerable Code
// admin/class-b2bking-admin.php // The plugin registers several AJAX actions intended for administrative use // but fails to verify if the requesting user has the 'manage_options' or 'manage_woocommerce' capability. add_action('wp_ajax_b2bking_set_users_in_group', array($this, 'b2bking_set_users_in_group')); --- // In admin/class-b2bking-admin.php (inferred location based on admin tool registration) public function b2bking_set_users_in_group() { // Verify the nonce provided in the request check_ajax_referer('b2bking_admin_nonce', 'security'); // VULNERABILITY: No check for current_user_can('manage_options') or similar admin capability $users = isset($_POST['users']) ? sanitize_text_field($_POST['users']) : ''; $group = isset($_POST['group']) ? sanitize_text_field($_POST['group']) : ''; // Proceed to modify user metadata based on input if (!empty($users) && !empty($group)) { // ... logic to update b2bking_customer_group meta ... } }
Security Fix
@@ -4096,12 +4096,14 @@ min-width: 65px; } .approval_badge.active{ - background: rgba(40, 167, 69, 0.1) !important; - color: #28a745 !important; + background: #f4f6f5 !important; + border: 1px solid #e5e9e7 !important; + color: #5d7466 !important; } .approval_badge.pending{ - background: rgba(255, 193, 7, 0.1) !important; - color: #ffc107 !important; + background: #fff8e5 !important; + border: 1px solid #f2dfad !important; + color: #9a6a00 !important; cursor: pointer; position: relative; } @@ -31,6 +31,9 @@ #b2bking_admin_form .checkbox input{ margin:0; } +.b2bking_settings_saved_swal_title { + font-size: 16px !important; +} .b2bking_button_color_gold.b2bking_button_color_gold_main button{ background: radial-gradient(141.77% 141.08% at 100.26% 99.25%, #cd4f72 0%, #e59a45 100%) !important; } @@ -45,13 +45,40 @@ $(this).closest('.message').transition('fade'); }); + var settingsSavedNoticeKey = 'b2bking_settings_saved_notice'; + // On Submit (Save Settings), Get Current Tab and Pass The Tab as a Setting. $('#b2bking_admin_form').on('submit', function() { let tabInput = document.querySelector('#b2bking_current_tab_setting_input'); tabInput.value = document.querySelector('.item.active').dataset.tab; + sessionStorage.setItem(settingsSavedNoticeKey, '1'); return true; }); + const urlParams = new URLSearchParams(window.location.search); + if ((urlParams.get('settings-updated') === 'true' || sessionStorage.getItem(settingsSavedNoticeKey) === '1') && typeof Swal !== 'undefined'){ + sessionStorage.removeItem(settingsSavedNoticeKey); + const Toast = Swal.mixin({ + toast: true, + position: 'bottom-end', + showConfirmButton: false, + timer: 1000, + timerProgressBar: false, + customClass: { + title: 'b2bking_settings_saved_swal_title' + }, + didOpen: (toast) => { + toast.addEventListener('mouseenter', Swal.stopTimer) + toast.addEventListener('mouseleave', Swal.resumeTimer) + } + }) + + Toast.fire({ + icon: 'success', + title: b2bking.settings_saved_successfully + }); + } + }); @@ -8132,6 +8132,7 @@ 'groupspage' => admin_url( 'admin.php?page=b2bking_groups'), 'saving' => esc_html__('Saving...','b2bking'), 'settings_saved' => esc_html__('Settings Saved','b2bking'), + 'settings_saved_successfully' => esc_html__('Settings saved successfully','b2bking'), 'users_have_been_moved' => esc_html__('All users have been moved to your chosen group','b2bking'), 'registration_form_shortcodes_text' => esc_html__('Registration Form Shortcodes','b2bking'), 'bulkorder_form_shortcodes_text' => esc_html__('Order Form Shortcodes','b2bking'),
Exploit Outline
To exploit this vulnerability, an attacker must have at least Shop Manager level access. 1. Login to the WordPress dashboard as a Shop Manager. 2. Navigate to a standard administrative page where the plugin enqueues its scripts (such as a Product Edit page) and extract the 'b2bking_admin_nonce' from the global 'b2bking' JavaScript object. 3. Identify the target User ID and the ID of a B2B group (b2bking_group) the attacker wishes to assign the user to. 4. Send a POST request to `/wp-admin/admin-ajax.php` with the action `b2bking_set_users_in_group`. The payload should include the extracted nonce in the 'security' parameter, the target User ID(s) in 'users', and the target Group ID in 'group'. 5. Because the plugin lacks a capability check, the AJAX request will succeed, updating the user's customer group and granting them associated B2B privileges or discounts.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.