Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-36675: ⚓ T332889 XSS in BlockLogFormatter due to unsafe message use

An issue was discovered in MediaWiki before 1.35.11, 1.36.x through 1.38.x before 1.38.7, 1.39.x before 1.39.4, and 1.40.x before 1.40.1. BlockLogFormatter.php in BlockLogFormatter allows XSS in the partial blocks feature.

CVE
#xss#vulnerability#php#auth

**

XSS in BlockLogFormatter due to unsafe message use

Closed, ResolvedPublicSecurity

**

  • Edit Task

  • Edit Related Tasks…

  • Edit Related Objects…

  • Mute Notifications

  • Protect as security issue

  • Award Token

  • Flag For Later

Found with r902363 which annotates some methods as unsafe. There are some genuine vulnerabilities in BlockLogFormatter, specifically in the code for partial blocks:

BlockLogFormatter.php#110-135

$actions = $params[6][‘actions’] ?? []; $actions = array_map( function ( $actions ) { return $this->msg( 'ipb-action-' . $actions )->text(); }, $actions );

$restrictions = []; if ( $pages ) { $restrictions[] = $this->msg( ‘logentry-partialblock-block-page’ ) ->numParams( count( $pages ) ) ->rawParams( $this->context->getLanguage()->listToText( $pages ) )->text(); }

if ( $namespaces ) { $restrictions[] = $this->msg( ‘logentry-partialblock-block-ns’ ) ->numParams( count( $namespaces ) ) ->rawParams( $this->context->getLanguage()->listToText( $namespaces ) )->text(); } $enablePartialActionBlocks = $this->context->getConfig() ->get( MainConfigNames::EnablePartialActionBlocks ); if ( $actions && $enablePartialActionBlocks ) { $restrictions[] = $this->msg( ‘logentry-partialblock-block-action’ ) ->numParams( count( $actions ) ) ->rawParams( $this->context->getLanguage()->listToText( $actions ) )->text(); // <-- Unsafe use of rawParams because $actions is built with Message::text() }

$params[6] = Message::rawParam( $this->context->getLanguage()->listToText( $restrictions ) );// <-- Unsafe use of rawParam because $restrictons is built with Message::text()

These can be reproduced by:

  • Adding <script>alert()</script> or something like that to ipb-action-* and logentry-partialblock-block-* messages
  • Enabling action blocks with $wgEnablePartialActionBlocks = true;
  • Blocking someone selecting all options for partial blocks
  • Going to their contributions page

Risk Rating

Medium

Author Affiliation

WMF Product

  • Task Graph

Event Timeline

Comment Actions

So for:

->rawParams( $this->context->getLanguage()->listToText( $actions ) )->text(); // <-- Unsafe use of rawParams because $actions is built with Message::text()

that should be resolved with an s/text()/parse()/, no? Which we’d also want to change for the message construction under the if ( $pages ) and if ( $namespaces ) conditionals, right? Unless that would somehow lead to double-escaping. Assuming it doesn’t, those mitigations should ensure that $restrictions shouldn’t be tainted within:

$params[6] = Message::rawParam( $this->context->getLanguage()->listToText( $restrictions ) );

Comment Actions

So for:

->rawParams( $this->context->getLanguage()->listToText( $actions ) )->text(); // <-- Unsafe use of rawParams because $actions is built with Message::text()

that should be resolved with an s/text()/parse()/, no?

When using the ipb-action-* messages, yes, I think so. Possibly escaped() instead of parse(), unless there’s a good reason to use the latter.

Which we’d also want to change for the message construction under the if ( $pages ) and if ( $namespaces ) conditionals, right? Unless that would somehow lead to double-escaping. Assuming it doesn’t, those mitigations should ensure that $restrictions shouldn’t be tainted within:

$params[6] = Message::rawParam( $this->context->getLanguage()->listToText( $restrictions ) );

Yes, I think replacing text() with escaped() in all the 3 conditionals should fix this, BUT I have no idea if this will break anything. I’m not familiar with LogFormatter and I’ve always found it to be a huge mess, particularly for how the escaping is controlled ($this>plaintext etc.). Maybe we need to manually vary the escaping on the value of $this->plaintext. I don’t really know…

Comment Actions

Yes, I think replacing text() with escaped() in all the 3 conditionals should fix this, BUT I have no idea if this will break anything. I’m not familiar with LogFormatter and I’ve always found it to be a huge mess, particularly for how the escaping is controlled ($this>plaintext etc.). Maybe we need to manually vary the escaping on the value of $this->plaintext. I don’t really know…

I think we should just get a patch up on gerrit for this and see how it tests. That’s the most reasonable approach IMO, especially since we’ve fixed many of these MW message output issues in the open. Unless there are strong objections…

Comment Actions

Yes, I think replacing text() with escaped() in all the 3 conditionals should fix this, BUT I have no idea if this will break anything. I’m not familiar with LogFormatter and I’ve always found it to be a huge mess, particularly for how the escaping is controlled ($this>plaintext etc.). Maybe we need to manually vary the escaping on the value of $this->plaintext. I don’t really know…

I think we should just get a patch up on gerrit for this and see how it tests. That’s the most reasonable approach IMO, especially since we’ve fixed many of these MW message output issues in the open. Unless there are strong objections…

No objections in the meantime, so I pushed the fix to gerrit to get the ball rolling.

Comment Actions

There’s a merge conflict when backporting to REL1_35 that I didn’t investigate yet.

Comment Actions

There’s a merge conflict when backporting to REL1_35 that I didn’t investigate yet.

I’ll take care of that.

Comment Actions

There’s a merge conflict when backporting to REL1_35 that I didn’t investigate yet.

I’ll take care of that.

Or maybe not? It’s rejecting my push for some reason. The conflict itself is easy to fix, a couple of places that use text() in master did not exist in 1.35.

Comment Actions

Thanks all, I’m leaving it up to the Security team to close this task and make it public when they’re comfortable with that.

Comment Actions

Thanks all, I’m leaving it up to the Security team to close this task and make it public when they’re comfortable with that.

Thanks for getting this done. I’ll make this task public now since all of the work was done in gerrit and the issue is now being tracked for the next release as well: T333617.

sbassett changed Author Affiliation from N/A to WMF Product.

sbassett changed the visibility from “Custom Policy” to "Public (No Login Required)".

Content licensed under Creative Commons Attribution-ShareAlike 3.0 (CC-BY-SA) unless otherwise noted; code licensed under GNU General Public License (GPL) or other open source licenses. By using this site, you agree to the Terms of Use, Privacy Policy, and Code of Conduct. · Wikimedia Foundation · Privacy Policy · Code of Conduct · Terms of Use · Disclaimer · CC-BY-SA · GPL

Related news

Debian Security Advisory 5447-1

Debian Linux Security Advisory 5447-1 - Multiple security issues were discovered in MediaWiki, a website engine for collaborative work, which could result in cross-site scripting, a bypass of vandalism protections or information disclosure.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907