Shortcodes Ultimate <= 7.4.7 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'su_lightbox' Shortcode
Description
The WP Shortcodes Plugin - Shortcodes Ultimate plugin for WordPress is vulnerable to Stored Cross-Site Scripting in all versions up to, and including, 7.4.7. This is due to insufficient input sanitization and output escaping in the 'src' attribute of the su_lightbox shortcode. 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
<=7.4.7What Changed in the Fix
Changes introduced in v7.4.8
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-0737 ## 1. Vulnerability Summary The **Shortcodes Ultimate** plugin (<= 7.4.7) is vulnerable to **Stored Cross-Site Scripting (XSS)** via the `su_lightbox` shortcode. The vulnerability exists because the plugin insufficiently sanitizes the `src` attribute. Wh…
Show full research plan
Exploitation Research Plan - CVE-2026-0737
1. Vulnerability Summary
The Shortcodes Ultimate plugin (<= 7.4.7) is vulnerable to Stored Cross-Site Scripting (XSS) via the su_lightbox shortcode. The vulnerability exists because the plugin insufficiently sanitizes the src attribute. While it performs a weak check for the string javascript and uses esc_attr() on the output, it fails to account for:
- Protocol Bypasses: Bypassing the
javascript:check usingdata:URIs. - JavaScript Sink Injection: The frontend JavaScript (Magnific Popup) reads the
data-mfp-srcattribute and uses it to dynamically construct HTML elements (like<img>or<iframe>). During this process, attribute-escaped characters (like") are interpreted as real quotes, allowing an attacker to break out of the constructed HTML tag's attributes.
2. Attack Vector Analysis
- Endpoint: Standard WordPress post/page creation/edition.
- Shortcode:
[su_lightbox] - Vulnerable Attribute:
src - Authentication Level: Authenticated (Contributor+). Contributors can create posts and use shortcodes by default.
- Preconditions: The
su_option_unsafe_featuressetting is typicallyonby default, but this vulnerability persists regardless of that setting as it lies in the core shortcode rendering logic.
3. Code Flow
- Entry Point: A user with Contributor+ permissions saves a post containing the
[su_lightbox]shortcode. - Processing: When the post is rendered, WordPress calls
do_shortcode(), which triggers the registered callbacksu_shortcode_lightboxinincludes/shortcodes/lightbox.php. - Vulnerable Function:
su_shortcode_lightbox($atts, $content)- Line 112:
$atts['src'] = su_do_attribute($atts['src'], true);(Processes placeholders). - Line 114:
if (strpos(strtolower($atts['src']), 'javascript') !== false)(Blacklist check forjavascript:protocol). - Line 124: The
srcis passed toesc_attr()and embedded in a<span>tag:return '<span class="su-lightbox..." data-mfp-src="' . esc_attr($atts['src']) . '" ...>';
- Line 112:
- Frontend Execution:
- The plugin enqueues
magnific-popupandsu-shortcodes(includes/js/su-shortcodes.js). - The JS initializes the lightbox on elements with class
.su-lightbox. - When a user clicks the lightbox trigger, Magnific Popup reads the
data-mfp-srcvalue using jQuery's.data()or.attr(). - Sink: Magnific Popup uses this value to construct the modal content. If
type="image", it creates an<img>tag. Iftype="iframe", it creates an<iframe>. Because it often uses string concatenation or jQuery's$()to build these elements, the payload executes.
- The plugin enqueues
4. Nonce Acquisition Strategy
No WordPress nonce is required to exploit this vulnerability because it is a Stored XSS triggered by the standard rendering of post content.
- The shortcode is processed during the
the_contentfilter execution. - The Contributor only needs to create or update a post, which uses standard WordPress nonces for the
post.phporpost-new.phpendpoints. These are managed automatically by a logged-in session.
5. Exploitation Strategy
Step-by-Step Plan
- Login as Contributor: Authenticate with Contributor credentials.
- Create Post: Use the WordPress REST API or standard post creation to save a post containing the malicious shortcode.
- Inject Payload: Use a payload that bypasses the
javascriptcheck and breaks out of the JS-constructed attribute.
Malicious Payloads
Option A: Attribute Breakout (via Image type)
This payload uses a double quote to break out of the src attribute when Magnific Popup constructs the <img> tag.
[su_lightbox type="image" src='https://example.com/logo.png" onerror="alert(window.origin
Summary
The Shortcodes Ultimate plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'su_lightbox' shortcode due to insufficient input validation and output escaping. Authenticated attackers with contributor-level permissions or higher can inject arbitrary scripts through the 'src' attribute, which are then executed by the frontend Magnific Popup library when the lightbox trigger is processed.
Vulnerable Code
// includes/shortcodes/lightbox.php line 114 if (strpos(strtolower($atts['src']), 'javascript') !== false) { return su_error_message('Lightbox', __('please specify correct source', 'shortcodes-ultimate')); } --- // includes/shortcodes/lightbox.php line 124 return '<span class="su-lightbox' . su_get_css_class($atts) . '" data-mfp-src="' . esc_attr($atts['src']) . '" data-mfp-type="' . sanitize_key($atts['type']) . '" data-mobile="' . sanitize_key($atts['mobile']) . '">' . do_shortcode($content) . '</span>';
Security Fix
@@ -111,7 +111,10 @@ $atts['src'] = su_do_attribute($atts['src'], true); - if (strpos(strtolower($atts['src']), 'javascript') !== false) { + if ( + strpos(strtolower($atts['src']), 'javascript') !== false || + strpos(strtolower($atts['src']), 'data:') !== false + ) { return su_error_message('Lightbox', __('please specify correct source', 'shortcodes-ultimate')); } @@ -121,5 +124,5 @@ su_query_asset('js', 'magnific-popup'); su_query_asset('js', 'su-shortcodes'); - return '<span class="su-lightbox' . su_get_css_class($atts) . '" data-mfp-src="' . esc_attr($atts['src']) . '" data-mfp-type="' . sanitize_key($atts['type']) . '" data-mobile="' . sanitize_key($atts['mobile']) . '">' . do_shortcode($content) . '</span>'; + return '<span class="su-lightbox' . su_get_css_class($atts) . '" data-mfp-src="' . esc_url($atts['src']) . '" data-mfp-type="' . sanitize_key($atts['type']) . '" data-mobile="' . sanitize_key($atts['mobile']) . '">' . do_shortcode($content) . '</span>'; }
Exploit Outline
The exploit targets the `su_lightbox` shortcode, which is available to any user with the ability to create or edit posts (Contributor+ by default). An attacker inserts a malicious shortcode like `[su_lightbox type="image" src='https://example.com/logo.png" onerror="alert(1)']Click Me[/su_lightbox]`. When a victim visits the page, the plugin renders the shortcode into a `<span>` element with the payload in the `data-mfp-src` attribute. The plugin's frontend JavaScript (Magnific Popup) reads this attribute to dynamically construct a modal element (e.g., an `<img>` tag). Because the JavaScript implementation does not properly re-sanitize the data when building the element's inner HTML or attributes, the injected quote breaks out of the `src` attribute, allowing the `onerror` handler to execute arbitrary JavaScript.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.