1. Vulnerability Background
- This issue is a Stored Cross-Site Scripting (XSS) vulnerability in the WC Builder – WooCommerce Page Builder for WPBakery WordPress plugin.
- It is triggered through insufficient sanitization and escaping of CSS-related shortcode parameters, primarily in the
wpbforwpbakery_product_additional_informationshortcode and several other product-related shortcodes. - Affected versions: all plugin releases up to and including 1.2.0.
- The attack is exploitable by authenticated users with Shop Manager-level access and above, which is significant because these users are common in WooCommerce environments and often allowed to edit product content.
- The vulnerability is critical because injected scripts are stored and executed later when any user loads the affected page, enabling session theft, privilege escalation, and other client-side compromise of administrative or storefront visitors.
2. Technical Details
Root cause analysis:
- The plugin builds inline CSS blocks by concatenating user-controlled values directly into
<style>content. - Examples of vulnerable code patterns:
".woocommerce .$unique_class h2{color:{$heading_color}; font-size:{$heading_font_size}; ... }""$styles[] = 'text-align:'. $text_align .'';"echo '<style type="text/css">' . $wpb_custom_css . '</style>';
- Parameters such as
heading_color,text_align,font_size,line_height, and various color attributes are accepted from shortcode attributes or stored metadata and reused without validation.
Attack vector and exploitation conditions:
- An authenticated attacker with Shop Manager or higher privileges can create or edit product content using WPBakery shortcodes or product settings.
- The attacker injects specially crafted values into CSS styling parameters.
- During page rendering, the plugin outputs those values inside a
<style>block or directly into HTML attributes without sufficient escaping. - A payload that closes the CSS rule or the
<style>tag can inject arbitrary HTML/JavaScript, e.g. via a value like:red;}</style><script>alert(1)</script><style>
- Because the content is stored in product metadata or shortcode parameters, the attack is persistent and affects any user who visits the injected page.
Security implications:
- Stored XSS in a WooCommerce context is high impact: it can affect administrators, shop managers, customers, and any other visitor to the product page.
- It may allow data exfiltration, account takeover, CSRF bypass, or exploitation of other vulnerabilities in the WordPress session.
- The vulnerability is further aggravated by the common use of WPBakery/shortcode-based styling in WooCommerce, making the attack surface broad.
3. Patch Analysis
What changed:
- A new sanitization helper was added in
includes/helper-functions.php:wpbforwpbakery_sanitize_css_value( $value )
- This function strips HTML tags and removes characters or sequences that can break out of CSS rules, such as
<,>,{,},;,"and script-related text. - It is applied to CSS-related input values across multiple files:
includes/addons/product_related.phpincludes/addons/product_short_description.phpincludes/addons/product_additional_information.phpincludes/addons/product_data_tab.phpincludes/addons/product_price.phpincludes/addons/product_title.phpincludes/addons/product_add_to_cart.phpwc-builder.php
- Additional hardening:
includes/helper-functions.phpnow wraps custom CSS class generation withesc_attr().woo_shop.phpnow strips tags from post metadata CSS output usingwp_strip_all_tags().
How the changes fix it:
- Unsafe CSS parameter values are cleaned before being inserted into inline CSS rules.
- The sanitization function prevents values from containing closing braces or closing style tags that would allow an attacker to escape the CSS context.
- Escaping class values prevents injection into HTML attributes.
- Stripping tags from metadata CSS output prevents raw
<script>insertion through stored CSS content.
Security improvements introduced:
- Centralized CSS value sanitization provides a reusable defense for multiple shortcode parameters.
- Output is now treated according to context: CSS values are sanitized before being embedded in
<style>blocks, and class values are escaped before HTML output. - The patch closes the common pattern of direct concatenation of user-controlled styling inputs into rendered page output.
4. Proof of Concept (PoC) Guide
Prerequisites:
- WordPress site running WC Builder – WooCommerce Page Builder for WPBakery plugin version <= 1.2.0.
- User account with Shop Manager or higher privileges.
- Ability to edit product content or add WPBakery shortcode parameters.
Step-by-step exploitation approach:
- Log in as a Shop Manager or administrator.
- Edit a product page or add a vulnerable shortcode block.
- Use a vulnerable shortcode such as
wpbforwpbakery_product_additional_information. - Supply a malicious value for a styling parameter, for example:
heading_color="red;}</style><script>alert('XSS')</script><style>"
- Save the product page.
- Open the product page in a browser, preferably as a different user or in a private window.
Expected behavior vs exploited behavior:
- Expected safe behavior: the page renders normally with the supplied styling value applied, and no script executes.
- Exploited behavior: the payload breaks out of the CSS block and causes the browser to execute injected JavaScript, such as
alert('XSS'). - The injected script executes whenever the page is viewed, demonstrating stored XSS.
How to verify the vulnerability exists:
- Inspect the page source or developer tools.
- Look for injected payload fragments in the
<style>block or adjacent HTML. - Confirm that the malicious script appears in the rendered output.
- After patching, verify that the value has been sanitized and no tags or script content remain in the CSS output.
5. Recommendations
Mitigation strategies:
- Upgrade the plugin to the patched version (1.2.1 or later) as soon as possible.
- If an immediate patch is unavailable, remove or disable the affected plugin.
- Restrict shop manager privileges where feasible and monitor changes to product content.
Detection methods:
- Search the database for suspicious values in shortcode parameters and product metadata, especially strings containing
</style>,<script>,expression(, or malformed CSS fragments. - Monitor HTTP responses for injected
<script>tags or malformed style blocks in product pages. - Use web application firewalls or scanning tools to detect XSS payloads in stored content.
Best practices to prevent similar issues:
- Validate and sanitize all user-controlled values before using them in rendered output.
- Apply context-appropriate escaping:
- sanitize CSS values before embedding in
<style>blocks. - use
esc_attr()for HTML attribute values. - use
esc_html()orwp_kses()for HTML content.
- sanitize CSS values before embedding in
- Prefer whitelisting valid values over blacklisting dangerous characters, especially for CSS properties.
- Centralize sanitization logic for repeated patterns instead of duplicating unsafe concatenation across multiple files.
- Treat authenticated input as untrusted, even from users with elevated roles.
- Conduct regular secure code reviews of shortcode handling and dynamic style generation in WordPress plugins.