From abb9d401eecfe6a58de47e395014df3c123bff39 Mon Sep 17 00:00:00 2001 From: vuckro Date: Wed, 10 Jun 2026 11:45:03 +0200 Subject: [PATCH] fix(security): escape customer/product output in Broadcast list table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit column_target_customers() and column_target_products() interpolated customer display names, email addresses and product names straight into HTML — including into single-quoted aria-label attributes. A customer controls their own display name, so a crafted name (display names are not HTML-escaped by WordPress on save and may contain quotes) is stored and then rendered unescaped when a network admin views the Broadcasts list, yielding stored XSS in the network-admin context. Escape each interpolated value for its context with esc_url() for links, esc_attr() for attribute values and esc_html() for text nodes. Co-Authored-By: Claude Fable 5 --- inc/list-tables/class-broadcast-list-table.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inc/list-tables/class-broadcast-list-table.php b/inc/list-tables/class-broadcast-list-table.php index 6eff74534..e78fcfb47 100644 --- a/inc/list-tables/class-broadcast-list-table.php +++ b/inc/list-tables/class-broadcast-list-table.php @@ -182,11 +182,11 @@ public function column_target_customers($item) { $email = $customer->get_email_address(); - $html = " + $html = " {$avatar}
- {$display_name} (#{$id}) - {$email} + " . esc_html($display_name) . " (#" . esc_html((string) $id) . ") + " . esc_html($email) . "
"; @@ -215,7 +215,7 @@ public function column_target_customers($item) { $customer_link = wu_network_admin_url('wp-ultimo-edit-customer', $url_atts); - $html .= ""; + $html .= ""; } if ($targets_count < 7) { @@ -363,7 +363,7 @@ public function column_target_products($item) { '; } - $html .= ""; + $html .= ""; } if ($product_count > 1 && $product_count < 5) {