Page MenuHomePhabricator

XSS on Special:MediaSearch (CVE-2021-42043)
Closed, ResolvedPublicSecurity

Description

This link pops up an alert message:

https://commons.wikimedia.org/w/index.php?search=temerair+temerair+temerair+temerair+intitle%3Ax+<script>alert%28%29<%2Fscript>&title=Special:MediaSearch&go=Go&type=image

The suggestion text (parameter to 'mediasearch-did-you-mean') is not HTML-escaped. You have to use 'intitle:' search operator in the query to exploit it (maybe some others also work), otherwise the search engine will "autocorrect" all of your code.

(I was testing things because the HTML-escaping issues in https://gerrit.wikimedia.org/r/c/mediawiki/extensions/MediaSearch/+/722974 made me think. But this is not actually related to any code changed in that patch.)

Event Timeline

I will generate a patch and post it here (not in Gerrit) ASAP. I assume this also needs to be backported as soon as is feasible.

Here is a patch for review:

Commit message (in case anyone wants to glance at this without downloading the whole thing):

Close an XSS vulnerability in "did you mean" message

The "mediasearch-did-you-mean" message allowed HTML in order to
present a direct link to a suggested search query to the user.

Unfortunately this opened a backdoor for XSS attacks. If a malicious
user had entered a <script> tag into the search input field, some
"did you mean" links would include that script. Such a link could
then be shared via URL to others, exposing them to the attack.

We have no reason to believe that this has occurred; the vulnerability
was discovered in the process of fixing an unrelated bug in the same
codebase.

This change addresses the vulnerability through the following measures:

* Changes the "mediasearch-did-you-mean" message so it doesn't contain
  markup, just plain text
* Removes the "RawHtmlMessages" key from extension.json
* Removes "{{{" and v-html outputs for this message in Mustache and Vue
  respectively
* Reworks the mustache and vue.js templates to construct the link inside
  of their sandboxes like so:
    <a href="{{ didYouMeanLink }}">{{ didYouMeanMessage }}</a>
  This ensures that all values are escaped before anything is displayed
* Updates the message documentation and all message files to only allow
  a single parameter; no i18n files should contain markup any longer.

Bug: T291600
Change-Id: If64eb5842237c92290d07ebc3fe14710d9de3fc2

Patch deployed a minute ago (02:06 UTC)

Jdforrester-WMF added a subscriber: Jdforrester-WMF.

Now landed in HEAD (which will be 1.38.0-wmf.2) as well as hot-deployed to 1.38.0-wmf.1; not deployed to 1.37.0-wmf.23.

Thanks for the quick fix.

I noticed that the current patch changes the interface so that the whole phrase is a link, instead of only the suggested query being a link, i.e. "Did you mean: foo" instead of "Did you mean: foo".

If you wanted to keep the previous design, MediaWiki's message system can support that, even without raw HTML messages: it's possible to have a normal message with a raw HTML parameter. This way the message can be safely edited by translators/admins, and we only need to take care about escaping what we put in the parameter. Like this:

en.json
"mediasearch-did-you-mean": "Did you mean: $1",
SpecialMediaSearch.php
'didYouMeanMessage' => $this->msg( 'mediasearch-did-you-mean' )
	->rawParams( Html::element( 'a', [ 'href' => $didYouMeanLink ], $didYouMean ) )
	->escaped(),
SERPWidget.mustache
{{{ didYouMeanMessage }}}

See https://www.mediawiki.org/wiki/Manual:Messages_API#Parameters for some (spare) documentation of rawParams(). This is widely used in MediaWiki, probably the most prominent place is in log messages (https://en.wikipedia.org/wiki/Special:Log), where every link on every line is a raw parameter.

Thanks @matmarex, I don't think I was aware that our message system could do that. We'll file a follow-up patch to restore the original design now that the vulnerability has been addressed.

sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett changed Risk Rating from N/A to Low.
sbassett moved this task from Incoming to Our Part Is Done on the Security-Team board.

I wasn't able to apply the security patch for 1.38.0-wmf.2. There were some conflicts that we tried to resolve, but in the end I got a message from git when trying to continue saying there were no changes, although it seemed like there still should have been localization changes. So I aborted.

The patch was merged into master (https://gerrit.wikimedia.org/r/c/mediawiki/extensions/MediaSearch/+/723020), and Gerrit says it is included in wmf/1.38.0-wmf.2, so I think you don't need the security patch any more.

Hey @jeena - I know that T276237 sometimes isn't updated as frequently as we might like, but we do try to call out anything that's been recently merged to main/master there as well.

sbassett assigned this task to egardner.
sbassett renamed this task from XSS on Special:MediaSearch to XSS on Special:MediaSearch (CVE-2021-42043).Thu, Oct 7, 8:36 PM