⚓ T357101 CVE-2024-34502: Special:MergeLexemes makes edits on GET requests without edit tokens
Page MenuHomePhabricator

CVE-2024-34502: Special:MergeLexemes makes edits on GET requests without edit tokens
Closed, ResolvedPublicSecurity

Description

Loading Special:MergeLexemes?from-id=L12345&to-id=L12346 will (attempt to) merge L12345 into L12346, even if the request was not a POST request, and even if it doesn’t contain an edit token.

Special:MergeItems and Special:RedirectEntity don’t have this problem, by the way – the TokenCheckInteractor checks both that the request has a valid token and that it was POSTed. (Though I don’t think it checks whether the token was in the POST body or in the request URL. I’m not sure if that’s a problem.) Special:MergeLexemes should use this interactor as well (and add the necessary hidden input to the form, of course).

Event Timeline

I really hope we can fix this in a way that doesn’t edit conflict with T356764, because I wouldn’t like to fix this task in public.

Okay, I think this should work:

diff --git a/src/MediaWiki/Specials/SpecialMergeLexemes.php b/src/MediaWiki/Specials/SpecialMergeLexemes.php
index dca2111390..71de16fd34 100644
--- a/src/MediaWiki/Specials/SpecialMergeLexemes.php
+++ b/src/MediaWiki/Specials/SpecialMergeLexemes.php
@@ -168,6 +168,18 @@ private function anonymousEditWarning(): string {
 	private function mergeLexemes( $serializedSourceId, $serializedTargetId ): void {
 		$sourceId = $this->getLexemeId( $serializedSourceId );
 		$targetId = $this->getLexemeId( $serializedTargetId );
+		// TODO inject interactor+localizer and move this check down a bit once this is public
+		// phpcs:disable MediaWiki.Classes.FullQualifiedClassName.Found
+		try {
+			\Wikibase\Repo\WikibaseRepo::getTokenCheckInteractor()
+				->checkRequestToken( $this->getContext(), 'wpEditToken' );
+		} catch ( \Wikibase\Repo\Interactors\TokenCheckException $e ) {
+			$message = \Wikibase\Repo\WikibaseRepo::getExceptionLocalizer()
+				->getExceptionMessage( $e );
+			$this->showErrorHTML( $message->parse() );
+			return;
+		}
+		// phpcs:enable
 
 		if ( !$sourceId ) {
 			$this->showInvalidLexemeIdError( $serializedSourceId );
 			return;
 		}
 		if ( !$targetId ) {
 			$this->showInvalidLexemeIdError( $serializedTargetId );
 			return;
 		}
 
 		try {
 			$this->mergeInteractor->mergeLexemes(

The mergeLexemes() call at the end there will probably be touched soon, so I put the check a bit higher up to (hopefully) avoid merge conflicts.

sbassett changed the task status from Open to In Progress.Feb 12 2024, 5:31 PM
sbassett triaged this task as Medium priority.
sbassett moved this task from Incoming to In Progress on the Security-Team board.
sbassett added subscribers: mmartorana, sbassett.

@mmartorana to review.

Hey @sbassett thanks for the triaging. Upon reviewing the provided code, there don't seem to be any apparent security concerns.

Okay, I think this should work:

diff --git a/src/MediaWiki/Specials/SpecialMergeLexemes.php b/src/MediaWiki/Specials/SpecialMergeLexemes.php
index dca2111390..71de16fd34 100644
--- a/src/MediaWiki/Specials/SpecialMergeLexemes.php
+++ b/src/MediaWiki/Specials/SpecialMergeLexemes.php
@@ -168,6 +168,18 @@ private function anonymousEditWarning(): string {
 	private function mergeLexemes( $serializedSourceId, $serializedTargetId ): void {
 		$sourceId = $this->getLexemeId( $serializedSourceId );
 		$targetId = $this->getLexemeId( $serializedTargetId );
+		// TODO inject interactor+localizer and move this check down a bit once this is public
+		// phpcs:disable MediaWiki.Classes.FullQualifiedClassName.Found
+		try {
+			\Wikibase\Repo\WikibaseRepo::getTokenCheckInteractor()
+				->checkRequestToken( $this->getContext(), 'wpEditToken' );
+		} catch ( \Wikibase\Repo\Interactors\TokenCheckException $e ) {
+			$message = \Wikibase\Repo\WikibaseRepo::getExceptionLocalizer()
+				->getExceptionMessage( $e );
+			$this->showErrorHTML( $message->parse() );
+			return;
+		}
+		// phpcs:enable
 
 		if ( !$sourceId ) {
 			$this->showInvalidLexemeIdError( $serializedSourceId );
 			return;
 		}
 		if ( !$targetId ) {
 			$this->showInvalidLexemeIdError( $serializedTargetId );
 			return;
 		}
 
 		try {
 			$this->mergeInteractor->mergeLexemes(

The mergeLexemes() call at the end there will probably be touched soon, so I put the check a bit higher up to (hopefully) avoid merge conflicts.

thank you for the patch @Lucas_Werkmeister_WMDE, it's been deployed

Lucas_Werkmeister_WMDE changed the task status from In Progress to Stalled.Feb 13 2024, 1:48 PM

Seems to work (tested at https://test.wikidata.org/wiki/Special:MergeLexemes?from-id=L2843&to-id=L338), thanks!

Moving back to Parent Tasks on our board – I think this is now just stalled until the next security release publishes the patch, at which point we’ll want to clean it up a bit more with a follow-up change on the master branch. (On the release branches, IMHO it’s enough to keep the patch as it is.)

Moving back to Parent Tasks on our board – I think this is now just stalled until the next security release publishes the patch, at which point we’ll want to clean it up a bit more with a follow-up change on the master branch. (On the release branches, IMHO it’s enough to keep the patch as it is.)

Yes, it should go out with the next supplemental release (T353904), due out by the end of March 2024. And since ext:WikibaseLexeme isn't bundled, it could theoretically be made public, and the patch backported, sooner. Which is handy if there are concerns about future conflicts, etc.

jnuche raised the priority of this task from Medium to Unbreak Now!.EditedMar 4 2024, 9:53 AM
jnuche subscribed.

Hi there, patch 01-T357101.patch is currently failing to apply. We will need a rebased version at the current release dir /srv/patches/1.42.0-wmf.20/extensions/WikibaseLexeme in the deployment server. Otherwise the upcoming 1.42.0-wmf.21 will be blocked.

EDIT: Sry, the rebased patch should of course go in a new dir for 1.42.0-wmf.21 will all other patches copied over. I can take care of that once a new patch is available

Rebased version:

But I don’t understand why you need this in the wmf.20 dir when it’s only conflicting against the upcoming wmf.21 branch?

But I don’t understand why you need this in the wmf.20 dir when it’s only conflicting against the upcoming wmf.21 branch?

@Lucas_Werkmeister_WMDE Sorry for the confusion. Please see my updated comment.

Thanks for the rebased patch, I'll add it to the deployment server.

Lucas_Werkmeister_WMDE lowered the priority of this task from Unbreak Now! to Medium.Mar 4 2024, 10:43 AM

Change #1013359 merged by jenkins-bot:

[mediawiki/extensions/WikibaseLexeme@master] SECURITY: Check edit token in Special:MergeLexemes

https://gerrit.wikimedia.org/r/1013359

Change #1016872 had a related patch set uploaded (by Lucas Werkmeister (WMDE); author: Lucas Werkmeister (WMDE)):

[mediawiki/extensions/WikibaseLexeme@REL1_41] SECURITY: Check edit token in Special:MergeLexemes

https://gerrit.wikimedia.org/r/1016872

Change #1016872 merged by jenkins-bot:

[mediawiki/extensions/WikibaseLexeme@REL1_41] SECURITY: Check edit token in Special:MergeLexemes

https://gerrit.wikimedia.org/r/1016872

Change #1016876 had a related patch set uploaded (by Lucas Werkmeister (WMDE); author: Lucas Werkmeister (WMDE)):

[mediawiki/extensions/WikibaseLexeme@REL1_40] SECURITY: Check edit token in Special:MergeLexemes

https://gerrit.wikimedia.org/r/1016876

Lucas_Werkmeister_WMDE changed the task status from Stalled to Open.Apr 4 2024, 1:17 PM

No longer stalled; I’m backporting the fix to release branches now, and we can also clean up the code.

Change #1016876 merged by jenkins-bot:

[mediawiki/extensions/WikibaseLexeme@REL1_40] SECURITY: Check edit token in Special:MergeLexemes

https://gerrit.wikimedia.org/r/1016876

Change #1016877 had a related patch set uploaded (by Lucas Werkmeister (WMDE); author: Lucas Werkmeister (WMDE)):

[mediawiki/extensions/WikibaseLexeme@REL1_39] SECURITY: Check edit token in Special:MergeLexemes

https://gerrit.wikimedia.org/r/1016877

Change #1016877 merged by Lucas Werkmeister (WMDE):

[mediawiki/extensions/WikibaseLexeme@REL1_39] SECURITY: Check edit token in Special:MergeLexemes

https://gerrit.wikimedia.org/r/1016877

Change #1017092 had a related patch set uploaded (by Lucas Werkmeister (WMDE); author: Lucas Werkmeister (WMDE)):

[mediawiki/extensions/WikibaseLexeme@master] Clean up edit token check in SpecialMergeLexemes

https://gerrit.wikimedia.org/r/1017092

Change #1017092 merged by jenkins-bot:

[mediawiki/extensions/WikibaseLexeme@master] Clean up edit token check in SpecialMergeLexemes

https://gerrit.wikimedia.org/r/1017092

Lucas_Werkmeister_WMDE claimed this task.

I think this is done; can someone™ make the task public? :)

sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".Apr 5 2024, 4:46 PM
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett changed Risk Rating from N/A to Low.
sbassett removed a project: Patch-For-Review.
Mstyles renamed this task from Special:MergeLexemes makes edits on GET requests without edit tokens to CVE-2024-34502: Special:MergeLexemes makes edits on GET requests without edit tokens.May 6 2024, 9:02 AM