CVE-2026-3504

Dokan: AI Powered WooCommerce Multivendor Marketplace Solution <= 4.3.1 - Unauthenticated Information Disclosure in Store Reviews REST API Endpoint

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.3.2
Patched in
2d
Time to patch

Description

The Dokan: AI Powered WooCommerce Multivendor Marketplace Solution plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.3.1 via the '/dokan/v1/stores/{id}/reviews' REST API endpoint. This is due to the 'prepare_reviews_for_response' method including reviewer email addresses, usernames, and user IDs in the API response. This makes it possible for unauthenticated attackers to extract email addresses, usernames, and user IDs of all customers who left reviews on any vendor's store. The Pro version of the plugin must be installed and activated, with store reviews enabled, in order to exploit the vulnerability.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=4.3.1
PublishedMay 1, 2026
Last updatedMay 2, 2026
Affected plugindokan-lite

What Changed in the Fix

Changes introduced in v4.3.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-3504 ## 1. Vulnerability Summary The Dokan Multivendor Marketplace plugin (dokan-lite) up to version 4.3.1 is vulnerable to **Unauthenticated Information Disclosure** via the Store Reviews REST API. The vulnerability exists because the `prepare_reviews_for_re…

Show full research plan

Exploitation Research Plan - CVE-2026-3504

1. Vulnerability Summary

The Dokan Multivendor Marketplace plugin (dokan-lite) up to version 4.3.1 is vulnerable to Unauthenticated Information Disclosure via the Store Reviews REST API. The vulnerability exists because the prepare_reviews_for_response method (and associated logic) fails to sanitize or exclude sensitive reviewer data—specifically email addresses, usernames, and user IDs—from the public API response. An unauthenticated attacker can query the reviews of any vendor store to harvest customer data.

2. Attack Vector Analysis

  • Endpoint: /wp-json/dokan/v1/stores/(?P<id>[\d]+)/reviews
  • Method: GET (Registered as WP_REST_Server::READABLE)
  • Authentication: None (Explicitly uses 'permission_callback' => '__return_true' in includes/REST/StoreController.php).
  • Parameter: id (The numerical ID of the Vendor/Store).
  • Preconditions:
    • Dokan Pro must be installed and activated.
    • The "Store Reviews" feature must be enabled.
    • At least one customer must have left a review for the target vendor.

3. Code Flow

  1. Route Registration: In includes/REST/StoreController.php, the register_routes method registers the reviews endpoint:
    register_rest_route(
        $this->namespace, '/' . $this->base . '/(?P<id>[\d]+)/reviews', [
            'args' => [ 'id' => [ ... ] ],
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_store_reviews' ],
                'args'                => $this->get_collection_params(),
                'permission_callback' => '__return_true', // Entry point is public
            ],
        ]
    );
    
  2. Callback Execution: When the endpoint is hit, get_store_reviews($request) is called.
  3. Data Retrieval: The method fetches reviews (which are stored as comments with a specific type, usually dokan_store_review).
  4. Data Preparation (Sink): For each review found, the controller calls a preparation method (referred to as prepare_reviews_for_response in the disclosure). This method maps the internal WordPress comment object to the API response array.
  5. Disclosure: The mapping includes fields like author_email or reviewer_email, author_user_id, and author_name directly from the user/comment record without checking if the requester is an administrator.

4. Nonce Acquisition Strategy

According to includes/REST/StoreController.php, the permission_callback for the GET request is __return_true.

No nonce is required for this exploitation because:

  1. It is a GET request.
  2. It is an unauthenticated "Information Disclosure" vulnerability.
  3. The REST API only requires the _wpnonce header/parameter if a session cookie is present (to prevent CSRF). For a "naked" unauthenticated request via the http_request tool, no nonce is needed.

5. Exploitation Strategy

  1. Identify Vendor ID: Enumerate vendor IDs (typically starts at 1 or 2). This can be done by hitting /wp-json/dokan/v1/stores or checking the /store/vendor-name URL on the frontend.
  2. Send API Request: Use the http_request tool to perform a GET request to the vulnerable endpoint.
  3. Analyze Response: Parse the JSON response and extract fields containing emails and usernames.

Request Template:

  • URL: http://localhost:8080/wp-json/dokan/v1/stores/{{VENDOR_ID}}/reviews
  • Method: GET
  • Headers:
    • Accept: application/json

6. Test Data Setup

  1. Install Plugins:
    • Install dokan-lite version 4.3.1.
    • Install and activate dokan-pro (required per vulnerability description).
  2. Configure Dokan:
    • Complete the setup wizard.
    • Ensure "Store Reviews" are enabled (Dokan > Settings > Selling Options > Enable Store Reviews).
  3. Create Entities:
    • Create a Vendor user (e.g., vendor_test).
    • Create a Customer user (e.g., victim_customer with email victim@example.com).
  4. Generate Data:
    • Log in as victim_customer.
    • Navigate to the Vendor's store page.
    • Leave a store review (Note: This is a store review, not a product review).
  5. Verify Vendor ID: Run wp user list --role=seller to find the Vendor's ID.

7. Expected Results

A successful exploit will return a JSON array of objects. Each object representing a review will contain:

  • id: The review ID.
  • author: An object containing the customer's username and user ID.
  • email (or author_email): The customer's cleartext email address.
  • content: The text of the review.

Example of vulnerable response fragment:

[
  {
    "id": 45,
    "author": {
      "id": 12,
      "name": "victim_customer",
      "url": ""
    },
    "author_email": "victim@example.com",
    "content": "Great store!",
    ...
  }
]

8. Verification Steps

  1. Confirm Output: Verify that the email address returned in the JSON matches the email of the victim_customer created in step 6.
  2. Unauthenticated Check: Ensure the request was made without any Cookie or Authorization headers.
  3. WP-CLI Cross-Check:
    # Get the customer's actual email
    wp user get victim_customer --field=user_email
    # Compare with the one found in the API response
    

9. Alternative Approaches

If /wp-json/dokan/v1/stores/{id}/reviews is blocked or returns 404:

  • Try the Store collection endpoint first to ensure the Store ID is correct: GET /wp-json/dokan/v1/stores.
  • If the Pro version features are not enabled, the route might exist but return an empty set. Check Dokan settings via wp option get dokan_selling to ensure reviews are enabled.
  • Check if the reviews are held for moderation; if so, approve them via wp comment list --status=hold and wp comment approve <id>.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Dokan plugin for WordPress discloses sensitive reviewer information including email addresses, usernames, and user IDs via the public '/dokan/v1/stores/{id}/reviews' REST API endpoint. Unauthenticated attackers can exploit this to harvest personal data of any customer who has left a review on a vendor's store.

Vulnerable Code

/* File: includes/REST/StoreController.php */

register_rest_route(
    $this->namespace, '/' . $this->base . '/(?P<id>[\d]+)/reviews', [
        'args' => [
            'id' => [
                'description' => __( 'Unique identifier for the object.', 'dokan-lite' ),
                'type'        => 'integer',
             ]
        ],
        [
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => [ $this, 'get_store_reviews' ],
            'args'                => $this->get_collection_params(),
            'permission_callback' => '__return_true',
        ],
    ]
);

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.1/assets/js/dokan-pro-features.asset.php /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.2/assets/js/dokan-pro-features.asset.php
--- /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.1/assets/js/dokan-pro-features.asset.php	2025-12-26 09:21:02.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.2/assets/js/dokan-pro-features.asset.php	2026-03-13 09:32:16.000000000 +0000
@@ -1 +1 @@
-<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => '47a74642fd5f0e3f2824');
+<?php return array('dependencies' => array('react', 'react-jsx-runtime', 'wp-dom-ready', 'wp-element', 'wp-i18n'), 'version' => 'c8a2b996431c317b9846');
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.1/assets/js/dokan-pro-features.js /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.2/assets/js/dokan-pro-features.js
--- /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.1/assets/js/dokan-pro-features.js	2025-11-26 09:41:10.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/4.3.2/assets/js/dokan-pro-features.js	2026-03-13 09:32:16.000000000 +0000
@@ -1,2 +1,2 @@
 /*! For license information please see dokan-pro-features.js.LICENSE.txt */
-(()=>{"use strict";var e={n:t=>{var a=t&&t.__esModule?()=>t.default:()=>t;return e.d(a,{a}),a},d:(t,a)=>{for(var l in a)e.o(a,l)&&!e.o(t,l)&&Object.defineProperty(t,l,{enumerable:!0,get:a[l]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)};const t=window.wp.domReady;var a,l,n,i,s,r,o,d,c,m,x,p,u,h,g,f,b,k,_,v,w,j,y,N,L,C,M,F,S,E,P,A,D,z,V=e.n(t);const H=dokanAdminDashboardSettings&&dokanAdminDashboardSettings["pro-features"]?dokanAdminDashboardSettings["pro-features"]:{} ... (truncated)

Exploit Outline

1. Identify the numerical Vendor ID of a target store (this can often be found by browsing the site's stores or querying the /dokan/v1/stores endpoint). 2. Construct an unauthenticated GET request to the REST API endpoint: /wp-json/dokan/v1/stores/{id}/reviews. 3. Send the request without any authentication headers or nonces. 4. Examine the JSON response objects, which contain the 'author_email', 'author_name' (username), and 'author' (containing user ID) for every user who submitted a store review.

Check if your site is affected.

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