Commit 4d6244ac532 for woocommerce
commit 4d6244ac53228c2ace7c770000b1fefa2ee8320a
Author: Liam Sarsfield <43409125+LiamSarsfield@users.noreply.github.com>
Date: Mon Aug 10 14:22:17 2026 +0100
Prevent protected product summaries before authentication (#67539)
Co-authored-by: Karol Manijak <20098064+kmanijak@users.noreply.github.com>
diff --git a/plugins/woocommerce/changelog/fix-protected-product-data-exposure b/plugins/woocommerce/changelog/fix-protected-product-data-exposure
new file mode 100644
index 00000000000..508011acc1f
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-protected-product-data-exposure
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Prevent password-protected products from exposing short descriptions before authentication.
diff --git a/plugins/woocommerce/includes/class-wc-embed.php b/plugins/woocommerce/includes/class-wc-embed.php
index 61ede414777..84bcc1ee09e 100644
--- a/plugins/woocommerce/includes/class-wc-embed.php
+++ b/plugins/woocommerce/includes/class-wc-embed.php
@@ -78,7 +78,7 @@ class WC_Embed {
if ( self::is_embedded_product() ) {
echo '<p><span class="wc-embed-price">' . $_product->get_price_html() . '</span></p>'; // WPCS: XSS ok.
- if ( ! empty( $post->post_excerpt ) ) {
+ if ( ! post_password_required( $post ) && ! empty( $post->post_excerpt ) ) {
ob_start();
woocommerce_template_single_excerpt();
$excerpt = ob_get_clean();
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductSummary.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductSummary.php
index fd65e5da0ec..1425405e9ee 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductSummary.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductSummary.php
@@ -195,7 +195,7 @@ class ProductSummary extends AbstractBlock {
$post_id = $block->context['postId'] ?? '';
$product = wc_get_product( $post_id );
- if ( ! $product ) {
+ if ( ! $product || post_password_required( $product->get_id() ) ) {
return '';
}
diff --git a/plugins/woocommerce/src/Blocks/Templates/SingleProductTemplate.php b/plugins/woocommerce/src/Blocks/Templates/SingleProductTemplate.php
index e97edf1d1d1..ef3f56373f1 100644
--- a/plugins/woocommerce/src/Blocks/Templates/SingleProductTemplate.php
+++ b/plugins/woocommerce/src/Blocks/Templates/SingleProductTemplate.php
@@ -140,6 +140,7 @@ class SingleProductTemplate extends AbstractTemplate {
'woocommerce/product-meta',
'woocommerce/product-rating',
'woocommerce/product-price',
+ 'woocommerce/product-summary',
'woocommerce/related-products',
'woocommerce/add-to-cart-with-options',
'woocommerce/product-gallery',
diff --git a/plugins/woocommerce/tests/php/includes/class-wc-embed-test.php b/plugins/woocommerce/tests/php/includes/class-wc-embed-test.php
new file mode 100644
index 00000000000..274110bd046
--- /dev/null
+++ b/plugins/woocommerce/tests/php/includes/class-wc-embed-test.php
@@ -0,0 +1,37 @@
+<?php
+declare( strict_types = 1 );
+
+/**
+ * Tests for the WC_Embed class.
+ */
+class WC_Embed_Test extends WC_Unit_Test_Case {
+
+ /**
+ * @testdox Password-protected product embeds should not expose the product summary.
+ */
+ public function test_embed_does_not_expose_password_protected_product_summary(): void {
+ $product = WC_Helper_Product::create_simple_product();
+ $product->set_short_description( 'Protected short description' );
+ $product->save();
+
+ wp_update_post(
+ array(
+ 'ID' => $product->get_id(),
+ 'post_password' => 'secret',
+ )
+ );
+
+ $this->go_to( get_permalink( $product->get_id() ) );
+ $GLOBALS['wp_query']->is_embed = true;
+
+ $this->assertTrue( WC_Embed::is_embedded_product(), 'The test request should be recognized as an embedded product.' );
+ $this->assertTrue( post_password_required(), 'The product should require a password.' );
+
+ ob_start();
+ $excerpt = WC_Embed::the_excerpt( 'Password required' );
+ ob_end_clean();
+
+ $this->assertStringContainsString( 'Password required', $excerpt, 'The password-protected excerpt should continue to be rendered.' );
+ $this->assertStringNotContainsString( 'Protected short description', $excerpt, 'The protected short description should not replace the password-protected excerpt.' );
+ }
+}