CVE-2026-10023

Dokan: AI Powered WooCommerce Multivendor Marketplace Solution <= 5.0.3 - Insecure Direct Object Reference to Authenticated (Custom+) Arbitrary Order Modification via Multiple AJAX Handlers

mediumAuthorization Bypass Through User-Controlled Key
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
5.0.4
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 all versions up to, and including, 5.0.3 via the change_order_status, add_order_note, delete_order_note, add_shipping_tracking_info, grant_access_to_download, and revoke_access_to_download AJAX handlers due to missing ownership validation on a user-controlled order ID key. This makes it possible for authenticated attackers, with custom vendor-level access and above, to modify the status of arbitrary orders, add attacker-controlled notes to any order (including customer-facing notes that trigger WooCommerce notification emails to buyers), delete any order note or WordPress comment by ID regardless of ownership, inject fake shipping tracking information on any order, and grant or revoke downloadable-product permissions on any order in the marketplace. Critically, nonce validity is not a barrier to exploitation: each of these AJAX handlers generates and embeds its nonce on the authenticated vendor's own dashboard order pages (e.g., /dashboard/orders/?order_id=OWN_ORDER_ID), which the attacker legitimately controls. The attacker harvests a valid nonce from their own order detail page and replays it against a victim order ID — the nonce only proves the request originates from a logged-in session, not that the order belongs to that vendor. This directly rebuts the prior rejection reasoning that 'users cannot generate valid nonces on command': vendor users can and do generate valid nonces on demand simply by loading their own dashboard pages. Source-code analysis confirmed the vulnerable code path is present and unpatched through version 5.0.1.

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<=5.0.3
PublishedJune 17, 2026
Last updatedJune 18, 2026
Affected plugindokan-lite

What Changed in the Fix

Changes introduced in v5.0.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-10023 ## 1. Vulnerability Summary **CVE-2026-10023** is a critical Insecure Direct Object Reference (IDOR) vulnerability in the **Dokan: AI Powered WooCommerce Multivendor Marketplace Solution** plugin (dokan-lite) up to version 5.0.3. The vulnerability exi…

Show full research plan

Exploitation Research Plan - CVE-2026-10023

1. Vulnerability Summary

CVE-2026-10023 is a critical Insecure Direct Object Reference (IDOR) vulnerability in the Dokan: AI Powered WooCommerce Multivendor Marketplace Solution plugin (dokan-lite) up to version 5.0.3.

The vulnerability exists in several AJAX handlers that manage order data. These handlers verify a WordPress nonce to ensure the request is part of a valid user session but fail to perform an ownership check to verify if the requesting vendor actually owns the order associated with the provided order_id. Because WordPress nonces for a specific action are consistent for a user's session regardless of the specific object (order) being viewed, a vendor can generate a valid nonce on their own order dashboard and "replay" it in a request targeting an order ID belonging to a different vendor.

2. Attack Vector Analysis

  • Vulnerable Endpoint: wp-admin/admin-ajax.php
  • AJAX Actions (Inferred from description):
    • dokan_change_order_status
    • dokan_add_order_note
    • dokan_delete_order_note
    • dokan_add_shipping_tracking_info
    • dokan_grant_access_to_download
    • dokan_revoke_access_to_download
  • Payload Parameter: order_id (The target order ID) and accompanying data (e.g., order_status, note, tracking_number).
  • Authentication Required: Authenticated user with Vendor (or higher) capabilities.
  • Preconditions: The attacker must have at least one order of their own (or access to the vendor dashboard) to generate the required nonce.

3. Code Flow (Inferred)

  1. Entry: The vendor sends a POST request to admin-ajax.php with an action like dokan_change_order_status.
  2. Nonce Verification: The handler calls check_ajax_referer( 'dokan_reviews_nonce', 'security' ) (or a similar nonce check). This succeeds because the attacker provides a nonce they legitimately generated on their own dashboard.
  3. Missing Authorization: The code retrieves the order_id from $_POST.
  4. Action Execution: The code proceeds to call WooCommerce functions like $order->update_status() or $order->add_order_note() directly using the user-provided order_id without checking if get_current_user_id() === $order->get_meta('_dokan_vendor_id').
  5. Sink: The database is updated, or an email notification is triggered to the customer of the victim vendor.

4. Nonce Acquisition Strategy

Dokan localizes its dashboard data into a global JavaScript object. To exploit this, the attacker needs the nonce used for order actions.

  1. Identify Shortcode: The Dokan dashboard is usually rendered via the [dokan-dashboard] shortcode on a specific page (commonly the /dashboard/ slug).
  2. Create/Access Vendor Dashboard:
    • The agent should ensure a Vendor user is created and a dashboard page exists:
      wp post create --post_type=page --post_title="Dashboard" --post_status=publish --post_content='[dokan-dashboard]'
  3. Navigate and Extract:
    • Navigate to the orders section of the dashboard: /dashboard/orders/.
    • Use browser_eval to extract the security nonce from the localized JS object.
    • Inferred JS Variable: window.dokan?.nonce or window.dokan?.order_nonce.
    • Note: Dokan often uses the key _wpnonce or security in the AJAX payload.

5. Exploitation Strategy

This plan focuses on dokan_change_order_status as the primary PoC.

Step 1: Target Identification

The attacker identifies a victim order_id (e.g., by incrementing their own Order IDs or through other reconnaissance).

Step 2: Payload Construction

  • URL: http://[target]/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=dokan_change_order_status&order_id=[VICTIM_ORDER_ID]&order_status=completed&security=[ATTACKER_NONCE]
    

Step 3: Triggering Note Injection (Alternative)

To demonstrate higher impact (Social Engineering/Phishing via Customer Emails):

  • Body:
    action=dokan_add_order_note&order_id=[VICTIM_ORDER_ID]&note=Your+order+requires+verification.+Visit+http://attacker.com/&note_type=customer&security=[ATTACKER_NONCE]
    

6. Test Data Setup

  1. Plugin Installation: Ensure woocommerce and dokan-lite (<= 5.0.3) are active.
  2. Configure Dokan: Enable "Vendor can update order status" in Dokan settings if necessary (usually default).
  3. Users:
    • vendor_victim: A vendor user.
    • vendor_attacker: A vendor user.
    • customer_user: A standard customer.
  4. Orders:
    • Create a product for vendor_victim.
    • As customer_user, purchase the victim's product. Let's assume this creates Order #100.
    • Create a product for vendor_attacker.
    • As customer_user, purchase the attacker's product. Let's assume this creates Order #101.

7. Expected Results

  • Success Response: The AJAX handler will typically return a JSON success message or 1.
  • System State Change: Order #100 (which belongs to vendor_victim) will have its status changed to completed despite the request being made by vendor_attacker.
  • Notification: The customer_user may receive a "Your order is complete" email from WooCommerce for an order the victim vendor has not yet fulfilled.

8. Verification Steps

After sending the http_request, verify the impact via WP-CLI:

  1. Check Order Status:
    wp wc order get 100 --field=status
    Expected: "completed"
  2. Check Order Notes (if note injection tested):
    wp wc order_note list 100 --fields=note
    Expected: Contains the attacker's malicious string.

9. Alternative Approaches

If dokan_change_order_status requires specific parameters not found in the initial trace:

  • Try dokan_add_shipping_tracking_info:
    • Params: order_id=[VICTIM_ID], tracking_number=FAKE123, shipping_provider=Other, security=[NONCE].
    • This is high impact as it affects customer trust and fulfillment tracking.
  • Try dokan_delete_order_note:
    • Params: order_id=[VICTIM_ID], note_id=[NOTE_ID], security=[NONCE].
    • Requires identifying a note_id (which are just WordPress comment IDs).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Dokan plugin is vulnerable to Insecure Direct Object Reference (IDOR) via several AJAX handlers (e.g., change_order_status, add_order_note) due to a lack of ownership validation on the order ID. Authenticated vendors can exploit this by harvesting a valid session nonce from their own dashboard and replaying it in requests against orders belonging to other vendors to modify statuses or inject notes.

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/5.0.3/assets/css/dokan-admin-dashboard.css /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/5.0.4/assets/css/dokan-admin-dashboard.css
--- /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/5.0.3/assets/css/dokan-admin-dashboard.css	2026-04-28 13:01:32.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/dokan-lite/5.0.4/assets/css/dokan-admin-dashboard.css	2026-06-08 11:00:08.000000000 +0000
@@ -1,4 +1,4 @@
-.dokan-withdraw-style-reset button:focus,.dokan-withdraw-style-reset .menu-toggle:hover,.dokan-withdraw-style-reset button:hover,.dokan-withdraw-style-reset .button:hover,.dokan-withdraw-style-reset .ast-custom-button:hover,.dokan-withdraw-style-reset input[type=reset]:hover,.dokan-withdraw-style-reset input[type=reset]:focus,.dokan-withdraw-style-reset input#submit:hover,.dokan-withdraw-style-reset input#submit:focus,.dokan-withdraw-style-reset input[type=button]:hover,.dokan-withdraw-style-reset input[type=button]:focus,.dokan-withdraw-style-reset input[type=submit]:hover,.dokan-withdraw-style-reset input[type=submit]:focus{background-color:var(--dokan-button-hover-color, #7047EB);border-color:var(--dokan-button-hover-background-color, #7047EB)}.dokan-withdraw-style-reset button{box-shadow:none;border:none}.dokan-withdraw-style-reset input{border:none}.dokan-withdraw-style-reset table,.dokan-withdraw-style-reset th,.dokan-withdraw-style-reset td{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;font-size:inherit;font-weight:inherit;text-align:inherit;vertical-align:inherit;box-sizing:border-box}.dokan-withdraw-style-reset input[type=text][role=combobox]{height:fit-content}.dokan-withdraw-style-reset .border{border-style:solid;border-width:1px}.dokan-withdraw-style-reset .border-b{border-bottom-width:1px;border-bottom-style:solid}
+.dokan-withdraw-style-reset button:focus,.dokan-withdraw-style-reset .menu-toggle:hover,.dokan-withdraw-style-reset button:hover,.dokan-withdraw-style-reset .button:hover,.dokan-withdraw-style-reset .ast-custom-button:hover,.dokan-withdraw-style-reset input[type=reset]:hover,.dokan-withdraw-style-reset input[type=reset]:focus,.dokan-withdraw-style-reset input#submit:hover,.dokan-withdraw-style-reset input#submit:focus,.dokan-withdraw-style-reset input[type=button]:hover,.dokan-withdraw-style-reset input[type=button]:focus,.dokan-withdraw-style-reset input[type=submit]:hover,.dokan-withdraw-style-reset input[type=submit]:focus{background-color:var(--dokan-button-hover-color, #7047EB);border-color:var(--dokan-button-hover-background-color, #7047EB)}.dokan-withdraw-style-reset button{box-shadow:none;border:none}.dokan-withdraw-style-reset input{border:none}.dokan-withdraw-style-reset table,.dokan-withdraw-style-reset th,.dokan-withdraw-style-reset td{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;font-size:inherit;font-weight:inherit;text-align:inherit;vertical-align:inherit;box-sizing:border-box}.dokan-withdraw-style-reset input[type=text][role=combobox]{height:fit-content}.dokan-withdraw-style-reset .border{border-style:solid;border-width:1px}.dokan-withdraw-style-reset .border-b{border-bottom-width:1px;border-bottom-style:solid}body:has(.dokan-withdraw-wrapper) .dokan-toaster{z-index:100001 !important}

Exploit Outline

To exploit this vulnerability, an attacker must have Vendor-level authentication. 1. The attacker logs into their vendor account and navigates to their own order dashboard (e.g., /dashboard/orders/) to obtain a valid security nonce for order actions from the localized JavaScript object (e.g., dokan.nonce). 2. The attacker identifies a target victim order ID (e.g., by enumerating IDs or using OSINT). 3. The attacker sends a POST request to wp-admin/admin-ajax.php with an action such as 'dokan_change_order_status' or 'dokan_add_order_note'. 4. The payload includes the target 'order_id' and the valid nonce they harvested. 5. Since the backend verifies only that the nonce is valid for the user's session and not that the user owns the specific order ID, the server processes the requested modification (e.g., changing status to 'completed' or adding a phishing note) on the victim's order.

Check if your site is affected.

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