Page MenuHomePhabricator

CVE-2025-32079:Saving the right content to MediaWiki:GrowthMentors.json can take down the site
Closed, ResolvedPublicSecurity

Description

MediaWiki:GrowthMentors.json is a part of community configuration, meaning its content is processed on request. This means its content needs to be carefully validated on each read and write, to ensure its content meets the code authors' assumptions and to avoid any fatal errors (which would take the site down). For this file, the validation is supposed to be handled by StructuredMentorListValidator class, called from ConfigHooks.

Unfortunately, the validation is currently broken (as an unintended side effect of T383330: Deprecate calling legacy Community Configuration). This means it is possible to abuse write access to MediaWiki:GrowthMentors.json to take down the site for at least some of its users. An example page content that would do this is this:

{
	"Mentors": {
		"43912": {
			"weight": "tramvaj"
		}
	}
}

With this as the content, any user who has user ID 43912 as their mentor assigned will experience fatal errors that look like this:

[58aa3efe-af0c-96f0-bdd8-67655dc99d32] /w/api.php?action=query&meta=userinfo TypeError: Argument 4 passed to GrowthExperiments\Mentorship\Mentor::__construct() must be of the type int, string given, called in /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/Mentorship/Provider/AbstractStructuredMentorProvider.php on line 90

Backtrace:

from /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/Mentorship/Mentor.php(29)
#0 /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/Mentorship/Provider/AbstractStructuredMentorProvider.php(90): GrowthExperiments\Mentorship\Mentor->__construct(MediaWiki\User\UserIdentityValue, null, string, string)
#1 /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/Mentorship/Provider/AbstractStructuredMentorProvider.php(63): GrowthExperiments\Mentorship\Provider\AbstractStructuredMentorProvider->newFromMentorDataAndUserIdentity(array, MediaWiki\User\UserIdentityValue, MediaWiki\User\User)
#2 /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/Mentorship/MentorPageMentorManager.php(134): GrowthExperiments\Mentorship\Provider\AbstractStructuredMentorProvider->newMentorFromUserIdentity(MediaWiki\User\UserIdentityValue, MediaWiki\User\User)
#3 /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/Mentorship/MentorPageMentorManager.php(181): GrowthExperiments\Mentorship\MentorPageMentorManager->getMentorForUser(MediaWiki\User\User, string)
#4 /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/HelpPanelHooks.php(273): GrowthExperiments\Mentorship\MentorPageMentorManager->getMentorForUserSafe(MediaWiki\User\User)
#5 /srv/mediawiki/php-1.44.0-wmf.12/extensions/GrowthExperiments/includes/HelpPanelHooks.php(197): GrowthExperiments\HelpPanelHooks->getMentorData(GrowthExperiments\Config\MediaWikiConfigReaderWrapper, MediaWiki\User\User, MediaWiki\Context\DerivativeContext, LanguageEn)
#6 /srv/mediawiki/php-1.44.0-wmf.12/includes/HookContainer/HookContainer.php(159): GrowthExperiments\HelpPanelHooks->onBeforePageDisplay(MediaWiki\Output\OutputPage, SkinApi)
#7 /srv/mediawiki/php-1.44.0-wmf.12/includes/HookContainer/HookRunner.php(991): MediaWiki\HookContainer\HookContainer->run(string, array, array)
#8 /srv/mediawiki/php-1.44.0-wmf.12/includes/Output/OutputPage.php(3198): MediaWiki\HookContainer\HookRunner->onBeforePageDisplay(MediaWiki\Output\OutputPage, SkinApi)
#9 /srv/mediawiki/php-1.44.0-wmf.12/includes/api/ApiFormatBase.php(349): MediaWiki\Output\OutputPage->output()
#10 /srv/mediawiki/php-1.44.0-wmf.12/includes/api/ApiMain.php(2240): MediaWiki\Api\ApiFormatBase->closePrinter()
#11 /srv/mediawiki/php-1.44.0-wmf.12/includes/api/ApiMain.php(1029): MediaWiki\Api\ApiMain->printResult(int)
#12 /srv/mediawiki/php-1.44.0-wmf.12/includes/api/ApiMain.php(953): MediaWiki\Api\ApiMain->handleException(TypeError)
#13 /srv/mediawiki/php-1.44.0-wmf.12/includes/api/ApiMain.php(915): MediaWiki\Api\ApiMain->executeActionWithErrorHandling()
#14 /srv/mediawiki/php-1.44.0-wmf.12/includes/api/ApiEntryPoint.php(153): MediaWiki\Api\ApiMain->execute()
#15 /srv/mediawiki/php-1.44.0-wmf.12/includes/MediaWikiEntryPoint.php(202): MediaWiki\Api\ApiEntryPoint->execute()
#16 /srv/mediawiki/php-1.44.0-wmf.12/api.php(44): MediaWiki\MediaWikiEntryPoint->run()
#17 /srv/mediawiki/w/api.php(3): require(string)
#18 {main}

This is because "tramvaj" (or any string) is not a valid value for mentor weight (only non-negative integers are valid in this context).

The expected failover behaviour when MediaWiki:GrowthMentors.json has invalid content is to behave as if there were no mentors (until someone fixes the invalid content manually).

Details

Risk Rating
Low
Author Affiliation
WMF Product
Related Changes in Gerrit:

Event Timeline

Security-Team: This is a mild Vuln-DoS. It requires two conditions for it to work: the attacker must be an administrator, plus the victim must have a mentor assigned (and Help Panel enabled). All accounts created since the deployment of Growth features would be vulnerable. I filled it as a security issue out of caution; feel free to publish if you deem it appropriate.

Urbanecm_WMF added a subscriber: JJMC89.

@JJMC89: This is not an issue in EditGrowthConfig (legacy Community Configuration), but in the way how we migrated mentorship to the CommunityConfiguration extension. Updated the tags accordingly.

There are two ways how we can fix this:

  1. Finish T367575 (currently marked as stalled)
  2. Register StructuredMentorListValidator as a validator with community configuration, and rely on CommunityConfiguration running the validator (instead of running it ourselves). Requires first finishing T384246.

Option 2 is quicker, and it requires relatively little changes, but option 1 is the end goal.

@Sgs @Michael Do you have any thoughts on this?

As discussed with @Urbanecm_WMF, let's go with Option 2. It is faster for now to create that capability in principle as @internal in a public change, and then have us making use of it as part of this security change.

Option 2 implemented in the patch above. @Michael @Sgs please approve via Phab, then I can deploy. T384246 has the matching CommunityConfiguration patch in Gerrit (with no context).

sbassett changed Risk Rating from N/A to Low.
Urbanecm_WMF triaged this task as High priority.
Urbanecm_WMF edited projects, added Growth-Team (Current Sprint); removed Growth-Team.
Urbanecm_WMF moved this task from Incoming to Code Review on the Growth-Team (Current Sprint) board.

I applied the patch locally and can confirm that it re-enables the previous validation. In particular, I can no longer save a string for the weight, or an integer for the username or message.

Some other mischief seems still possible (saving too long an intro message, etc.) but that does not seem security-relevant.

Thus, I'm giving my virtual +2 to the patch above.

Some other mischief seems still possible (saving too long an intro message, etc.) but that does not seem security-relevant.

Right. The previous code interpreted warnings as blocking, while the new code doesn't do that (instead, we have the validatePermissively concept). We can fix that later, I filled T384445 (privately for now) to ensure we do not forget that.

14:56 <urbanecm> !log Deployed security patch for T384244
14:56 <+stashbot> Logged the message at https://wikitech.wikimedia.org/wiki/Server_Admin_Log

Deployed to production (including the corresponding CommunityConfiguration change).

@sbassett Is it ok for us to backport this to Gerrit at this point? Or is there anything else your team would like to do first? For the record, GrowthExperiments is a regular extension (that is not a part of the release tarball).

@sbassett Is it ok for us to backport this to Gerrit at this point? Or is there anything else your team would like to do first? For the record, GrowthExperiments is a regular extension (that is not a part of the release tarball).

Yes. I'll add it for the next supplemental release as well. Thanks.

Change #1114020 had a related patch set uploaded (by Urbanecm; author: Urbanecm):

[mediawiki/extensions/GrowthExperiments@master] SECURITY: Register CommunityStructuredMentorListValidator

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

Change #1114020 merged by jenkins-bot:

[mediawiki/extensions/GrowthExperiments@master] SECURITY: Register CommunityStructuredMentorListValidator

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

Checked in beta cluster and testwiki wmf.14 - MediaWiki:GrowthMentors.json handles invalid input correctly, i.e. the input is not save, the error message is displayed to a user.

@sbassett Is it ok for us to backport this to Gerrit at this point? Or is there anything else your team would like to do first? For the record, GrowthExperiments is a regular extension (that is not a part of the release tarball).

Yes. I'll add it for the next supplemental release as well. Thanks.

Given the issue was fixed publicly, is it OK to publish the task at this point? It would allow us to publish & fix T384445 as well (which does not have security implications, but would enable anyone to guess the existence of this task as well).

Given the issue was fixed publicly, is it OK to publish the task at this point?

Yes, totally fine.

Urbanecm changed the visibility from "Custom Policy" to "Public (No Login Required)".Feb 3 2025, 10:47 PM
Urbanecm changed the edit policy from "Custom Policy" to "All Users".

Given the issue was fixed publicly, is it OK to publish the task at this point?

Yes, totally fine.

Done. Thank you!

Mstyles renamed this task from Saving the right content to MediaWiki:GrowthMentors.json can take down the site to CVE-2025-32079:Saving the right content to MediaWiki:GrowthMentors.json can take down the site.Apr 11 2025, 5:02 PM