Page MenuHomePhabricator

Unescaped message used in HTML on Special:Contributions (CVE-2020-25812)
Closed, ResolvedPublicSecurity

Description

On Special:Contributions, the NS filter uses unescaped messages as keys in the 'option' key for an HTMLForm specifier (source):

$fields['nsFilters'] = [
	// ...
	'options' => [
		$this->msg( 'invert' )->text() => 'nsInvert',
		$this->msg( 'namespace_association' )->text() => 'associated',
	],

This is vulnerable to a mild XSS in case one of those messages is changed to include raw HTML.

The issue was spotted by taint-check.

Event Timeline

s/text/escaped/ ?

Yeah, that seems the "right thing to do"™.

Should probably security-deploy sometime soon as opposed to gerrit, just to be safe. Special page tests pass but I'm not sure if it might upset anything in production.

From 376cfd4aa749d337067982353ab334a139cf3b8e Mon Sep 17 00:00:00 2001
From: sbassett <sbassett@wikimedia.org>
Date: Mon, 22 Jun 2020 16:16:15 -0500
Subject: [PATCH] Escape messages used as keys on Special:Contributions

Use escaped() instead of text() for message options keys

Bug: T255918
---
 includes/specials/SpecialContributions.php | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php
index 1a6d04f30d..eeee786123 100644
--- a/includes/specials/SpecialContributions.php
+++ b/includes/specials/SpecialContributions.php
@@ -590,8 +590,8 @@ class SpecialContributions extends IncludableSpecialPage {
            // See resources/src/mediawiki.special.recentchanges.js
            'infusable' => true,
            'options' => [
-               $this->msg( 'invert' )->text() => 'nsInvert',
-               $this->msg( 'namespace_association' )->text() => 'associated',
+               $this->msg( 'invert' )->escaped() => 'nsInvert',
+               $this->msg( 'namespace_association' )->escaped() => 'associated',
            ],  
            'default' => $nsFilters,
            'section' => 'contribs-top',
-- 
2.22.0
sbassett added a project: user-sbassett.
sbassett moved this task from Backlog to In Progress on the user-sbassett board.

Should probably security-deploy sometime soon as opposed to gerrit, just to be safe. Special page tests pass but I'm not sure if it might upset anything in production.

Let's try and see if something explodes? :-)

Jokes aside, I tried grepping those messages on codesearch and they're always used with ->text(), so they're not meant to contain any HTML, so nothing should break.

As for the patch, there's a cleaner alternative: using options-messages instead of options (see example here), as it already escapes stuff. I thought it would only work for values, but in fact it works for keys.

On a related note, LogEventsList has the same problem, see here:

private function getFiltersDesc( $filter ) {
	foreach ( $filter as $type => $val ) {
		// ...
		$options[ $message->text() ] = $type; // Line 214
	}
	return [
		// ...
		'options' => $options,
	];
}

Shall I open a new task for that, or do you want to include this fix in the same patch? For LogEventsList, options-messages cannot be used, so the fix is s/text/escaped/ at line 214.

Jokes aside, I tried grepping those messages on codesearch and they're always used with ->text(), so they're not meant to contain any HTML, so nothing should break.

As for the patch, there's a cleaner alternative: using options-messages instead of options (see example here), as it already escapes stuff. I thought it would only work for values, but in fact it works for keys.

Sounds good. Here's an updated version of the patch, which I can try to deploy during next week's (2020-06-29) security window:

From 624dc78883a117963fec1aa996fb374b36441323 Mon Sep 17 00:00:00 2001
From: sbassett <sbassett@wikimedia.org>
Date: Mon, 22 Jun 2020 16:16:15 -0500
Subject: [PATCH] Escape messages used as keys on Special:Contributions

Use options-messages instead of text() for message-based options keys

Bug: T255918
---
 includes/specials/SpecialContributions.php | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/includes/specials/SpecialContributions.php b/includes/specials/SpecialContributions.php
index 1a6d04f30d..22da6b7c8d 100644
--- a/includes/specials/SpecialContributions.php
+++ b/includes/specials/SpecialContributions.php
@@ -589,9 +589,9 @@ class SpecialContributions extends IncludableSpecialPage {
            // `contribs-ns-filters` class allows these fields to be toggled on/off by JavaScript.
            // See resources/src/mediawiki.special.recentchanges.js
            'infusable' => true,
-           'options' => [
-               $this->msg( 'invert' )->text() => 'nsInvert',
-               $this->msg( 'namespace_association' )->text() => 'associated',
+           'options-messages' => [
+               'invert' => 'nsInvert',
+               'namespace_association' => 'associated',
            ],  
            'default' => $nsFilters,
            'section' => 'contribs-top',
-- 
2.22.0

Shall I open a new task for that, or do you want to include this fix in the same patch? For LogEventsList, options-messages cannot be used, so the fix is s/text/escaped/ at line 214.

Yeah, let's file a new bug.

Update: filed as T256171.

sbassett triaged this task as Medium priority.Jun 23 2020, 7:35 PM

Sounds good. Here's an updated version of the patch, which I can try to deploy during next week's (2020-06-29) security window:
[snip]

Tested it, works fine. Approved, please go ahead and deploy whenever you wish.

Deployed. Holding for next security release.

sbassett moved this task from In Progress to Done on the user-sbassett board.

Looks like this isn't needed for REL1_31 - rMW2bb8515286da: Make Special:Contributions use OOUI added it, which is only in REL1_34

Resolving for ease of tracking in parent

Reedy changed the visibility from "Custom Policy" to "Public (No Login Required)".Sep 24 2020, 11:14 PM
Reedy changed the edit policy from "Custom Policy" to "All Users".
Legoktm renamed this task from Unescaped message used in HTML on Special:Contributions to Unescaped message used in HTML on Special:Contributions (CVE-2020-25812).Sep 27 2020, 11:51 AM