Blocksy Companion <= 2.1.45 - Authenticated (Editor+) Stored Cross-Site Scripting via 'product_description' Parameter
Description
The Blocksy Companion plugin for WordPress is vulnerable to Stored Cross-Site Scripting via admin settings in all versions up to, and including, 2.1.45 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with editor-level permissions and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page. This only affects multi-site installations and installations where unfiltered_html has been disabled.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:H/PR:H/UI:N/S:C/C:L/I:L/A:NTechnical Details
<=2.1.45What Changed in the Fix
Changes introduced in v2.1.46
Source Code
WordPress.org SVNThis research plan targets **CVE-2026-12430**, a Stored Cross-Site Scripting (XSS) vulnerability in the **Blocksy Companion** plugin. The vulnerability is located in the plugin's settings, specifically within the "White Label" extension's `product_description` parameter. ### 1. Vulnerability Summar…
Show full research plan
This research plan targets CVE-2026-12430, a Stored Cross-Site Scripting (XSS) vulnerability in the Blocksy Companion plugin. The vulnerability is located in the plugin's settings, specifically within the "White Label" extension's product_description parameter.
1. Vulnerability Summary
The Blocksy Companion plugin (<= 2.1.45) fails to adequately sanitize and escape the product_description parameter within its admin settings. While the plugin utilizes wp_kses_post() for some fields, this filter is insufficient to prevent XSS when unfiltered_html is disabled (e.g., for Editors on a Multisite or restricted environments), as it allows tags and attributes (like <a> or style) that can be used to execute JavaScript in specific contexts, or it may be omitted entirely during rendering in the admin dashboard.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php?action=customize_save - Method: POST
- Vulnerable Parameter:
customized(JSON payload) - Setting ID:
blocksy_ext_white_label_settings[product_description](inferred fromblocksy-companion.phpline 51 and CVE description) - Authentication: Authenticated, Editor or higher (requires
edit_theme_optionscapability). - Precondition: The "White Label" extension must be active and the site must have
unfiltered_htmldisabled for the attacker's role.
3. Code Flow
- Persistence: An Editor uses the WordPress Customizer or the Blocksy Dashboard to update the "Product Description". The request is sent to
admin-ajax.phpwith thecustomize_saveaction. - Storage: The values are processed by the Customizer API and stored in the
wp_optionstable under the option nameblocksy_ext_white_label_settings. - Retrieval: In
blocksy-companion.php, the settings are retrieved:// line 51 $blocksy_wl_settings = apply_filters( 'blocksy:ext:white-label:settings', get_option( 'blocksy_ext_white_label_settings', [] ) ); - Sink: The
product_descriptionis rendered in the Blocksy Dashboard (/wp-admin/admin.php?page=ct-dashboard) to identify the plugin. If the output is rendered using a rawechoor insufficient escaping, the XSS payload executes in the context of any user (including Administrators) viewing the dashboard.
4. Nonce Acquisition Strategy
This exploit requires the customize_save nonce. Since the attacker is authenticated as an Editor, they can extract this from the Customizer interface.
- Navigate to the WordPress Customizer:
/wp-admin/customize.php. - The nonce is stored in the global JavaScript object
_wpCustomizeSettings. - Use the
browser_evaltool to extract the nonce:- Variable:
window._wpCustomizeSettings.nonce.save
- Variable:
5. Exploitation Strategy
- Preparation: Log in as an Editor. Ensure the "White Label" extension is active (see Test Data Setup).
- Nonce Extraction: Navigate to
/wp-admin/customize.phpand runbrowser_eval("window._wpCustomizeSettings.nonce.save"). - Craft Payload: Create a JSON object for the
customizedparameter.{ "blocksy_ext_white_label_settings": { "product_description": "Custom Description<script>alert(document.domain)</script>" } } - Execute Injection: Send the following request via the
http_requesttool:- URL:
[TARGET_URL]/wp-admin/admin-ajax.php?action=customize_save - Method: POST
- Headers:
Content-Type: application/x-www-form-urlencoded - Body:
wp_customize=on& nonce=[EXTRACTED_NONCE]&
- URL:
Summary
The Blocksy Companion plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'product_description' parameter in the 'White Label' extension settings. Authenticated attackers with Editor-level permissions and above can inject arbitrary web scripts into this field, which then execute when an administrator accesses the Blocksy Dashboard.
Vulnerable Code
// blocksy-companion.php line 51 if ( in_array( 'white-label', $blocksy_active_extensions ) && ($blocksy_fs_instance->is_plan( 'agency' ) || $blocksy_fs_instance->is_plan( 'agency_v2' )) ) { $blocksy_wl_settings = apply_filters( 'blocksy:ext:white-label:settings', get_option( 'blocksy_ext_white_label_settings', [] ) ); if ( $blocksy_wl_settings && isset( $blocksy_wl_settings['hide_billing_account'] ) && $blocksy_wl_settings['hide_billing_account'] && !is_multisite() ) { $blocksy_has_account = false; } }
Security Fix
@@ -3,14 +3,14 @@ /* Plugin Name: Blocksy Companion Description: This plugin is the companion for the Blocksy theme, it runs and adds its enhacements only if the Blocksy theme is installed and active. -Version: 2.1.45 +Version: 2.1.46 Author: CreativeThemes Author URI: https://creativethemes.com Text Domain: blocksy-companion Domain Path: /languages/ License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html -Requires at least: 6.5 +Requires at least: 6.7 Requires PHP: 7.0 */ if ( !defined( 'ABSPATH' ) ) { @@ -45,13 +45,17 @@ return ob_get_clean(); } -function blocksy_ext_cookies_checkbox($prefix = '') { +function blocksy_ext_cookies_checkbox($prefix = '', $unique_suffix = '') { ob_start(); if (! empty($prefix)) { $prefix = '_' . $prefix; } + $input_id = ! empty($unique_suffix) + ? 'gdprconfirm_newsletter-' . sanitize_html_class($unique_suffix) + : 'gdprconfirm' . $prefix; + $message = blocksy_companion_theme_functions()->blocksy_get_theme_mod( 'forms_cookie_consent_content', blocksy_companion_safe_sprintf( @@ -70,14 +74,14 @@ blocksy_html_tag_e( 'input', [ - 'id' => 'gdprconfirm' . $prefix, + 'id' => $input_id, 'class' => 'ct-checkbox', 'name' => 'gdprconfirm', 'type' => 'checkbox', 'required' => true ] ); - ?><label for="gdprconfirm<?php echo esc_attr($prefix) ?>"><?php echo wp_kses_post($message) ?></label> + ?><label for="<?php echo esc_attr($input_id) ?>"><?php echo wp_kses_post($message) ?></label> </p>
Exploit Outline
The exploit is achieved by an authenticated user with Editor or higher permissions (specifically those with 'edit_theme_options' capabilities). 1. The attacker navigates to the WordPress Customizer ('/wp-admin/customize.php') and extracts the 'customize_save' nonce from the 'window._wpCustomizeSettings.nonce.save' object. 2. A POST request is sent to '/wp-admin/admin-ajax.php?action=customize_save' with 'wp_customize=on', the extracted nonce, and a 'customized' JSON payload. 3. The payload contains an entry for 'blocksy_ext_white_label_settings' with a 'product_description' attribute containing a malicious script, such as '<script>alert(document.domain)</script>'. 4. The script is stored in the site's options and will execute in the session of any administrator who views the plugin's dashboard.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.