From 22bab839ce50fac0387f0fb1aef48e338d64ae2a Mon Sep 17 00:00:00 2001
From: STran <stran@wikimedia.org>
Date: Mon, 1 Sep 2025 05:25:27 -0700
Subject: [PATCH] SECURITY: Escape XSS vector in UserInfoCard

What:
- Escape messages generated in CheckUserUserInfoCardService for groups
  (local and global) before they're returned to the front-end

Bug: T403289
Change-Id: Iacd0287259cb250ea7c32fbfc1365b89b263e576
---
 src/Services/CheckUserUserInfoCardService.php | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/Services/CheckUserUserInfoCardService.php b/src/Services/CheckUserUserInfoCardService.php
index 8aad2212..9fcb7fe0 100644
--- a/src/Services/CheckUserUserInfoCardService.php
+++ b/src/Services/CheckUserUserInfoCardService.php
@@ -139,14 +139,14 @@ class CheckUserUserInfoCardService {
 		$groupMessages = [];
 		foreach ( $groups as $group ) {
 			if ( $this->context->msg( "group-$group" )->exists() ) {
-				$groupMessages[] = $this->context->msg( "group-$group" )->text();
+				$groupMessages[] = $this->context->msg( "group-$group" )->escaped();
 			}
 		}
 		$userInfo['groups'] = '';
 		if ( $groupMessages ) {
 			$userInfo['groups'] = $this->context->msg( 'checkuser-userinfocard-groups' )
 				->params( Message::listParam( $groupMessages, ListType::COMMA ) )
-				->text();
+				->parse();
 		}
 
 		if ( !isset( $userInfo['totalEditCount'] ) ) {
@@ -168,14 +168,14 @@ class CheckUserUserInfoCardService {
 			foreach ( $globalGroups as $group ) {
 				if ( $this->context->msg( "group-$group" )->exists() ) {
 					$globalGroupMessages[] = $this->context->msg( "group-$group" )
-						->text();
+						->escaped();
 				}
 			}
 			$userInfo['globalGroups'] = '';
 			if ( $globalGroupMessages ) {
 				$userInfo['globalGroups'] = $this->context->msg( 'checkuser-userinfocard-global-groups' )
 					->params( Message::listParam( $globalGroupMessages, ListType::COMMA ) )
-					->text();
+					->parse();
 			}
 
 			if ( $centralAuthUser->isLocked() ) {
-- 
2.43.0

