Commit 64a42954fe9 for woocommerce
commit 64a42954fe92cf92573de791551528e6f7851593
Author: Chris Lilitsas <1105590+xristos3490@users.noreply.github.com>
Date: Fri Oct 23 17:10:38 2026 +0300
Escape the order status tooltip as an attribute in the orders list (#70061)
fix: escape order status tooltip as an attribute in the orders list
The tooltip went through wp_kses_post() into data-tip. On WordPress 7.2
kses decodes " in text, so a quote in a status label closed the
attribute. Use esc_attr() instead.
diff --git a/plugins/woocommerce/changelog/fix-order-status-tooltip-escaping b/plugins/woocommerce/changelog/fix-order-status-tooltip-escaping
new file mode 100644
index 00000000000..70103d09608
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-order-status-tooltip-escaping
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Escape the order status tooltip in the orders list as an attribute, so quotes in a status label no longer break its markup on WordPress 7.2.
diff --git a/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php b/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php
index 65716f679a2..aa41aef1435 100644
--- a/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php
+++ b/plugins/woocommerce/src/Internal/Admin/Orders/ListTable.php
@@ -1238,7 +1238,7 @@ class ListTable extends WP_List_Table {
}
if ( $tooltip ) {
- printf( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), wp_kses_post( $tooltip ), esc_html( $status_name ) );
+ printf( '<mark class="order-status %s tips" data-tip="%s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), esc_attr( $tooltip ), esc_html( $status_name ) );
} else {
printf( '<mark class="order-status %s"><span>%s</span></mark>', esc_attr( sanitize_html_class( 'status-' . $order->get_status() ) ), esc_html( $status_name ) );
}
diff --git a/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php b/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php
index e962a51cfb6..5e869b945cf 100644
--- a/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php
+++ b/plugins/woocommerce/tests/php/src/Internal/Admin/Orders/ListTableTest.php
@@ -493,6 +493,30 @@ class ListTableTest extends \WC_Unit_Test_Case {
$this->assertCount( 2, $items, 'An invalid date filter should be ignored and all orders shown' );
}
+ /**
+ * @testdox Quotes in an order status label cannot break out of the status column tooltip attribute.
+ */
+ public function test_render_order_status_column_escapes_tooltip_attribute(): void {
+ $order = \WC_Helper_Order::create_order();
+ $order->set_status( OrderStatus::PROCESSING );
+ $order->save();
+
+ $filter = function ( $labels ) {
+ $labels[ OrderStatus::PROCESSING ] = 'Paid" onmouseover="alert(1)';
+ return $labels;
+ };
+ add_filter( 'woocommerce_get_order_status_labels', $filter );
+
+ ob_start();
+ $this->sut->render_order_status_column( $order );
+ $output = ob_get_clean();
+
+ remove_filter( 'woocommerce_get_order_status_labels', $filter );
+
+ $this->assertStringContainsString( 'data-tip="Paid" onmouseover="alert(1)"', $output );
+ $this->assertStringNotContainsString( 'onmouseover="', $output );
+ }
+
/**
* @testdox Ordering by date also orders by ID, so orders created at the same time keep a stable order.
* @testWith [{}]