Page MenuHomePhabricator

CVE-2022-28201: Title::newMainPage() goes into an infinite recursion loop if it points to a local interwiki
Closed, ResolvedPublicSecurity

Description

When parsing titles, if given a bare local interwiki, like [[localiw:]], then it turns into a local link to the main page using Title::newMainPage() (https://gerrit.wikimedia.org/g/mediawiki/core/+/b44af6c975d0271b3cf305441636de376b6d5995/includes/title/MediaWikiTitleCodec.php#441).

So if the "mainpage" message, which is customizable on-wiki by "editinterface" users, is just a bare local interwiki, e.g. localiw:, MediaWiki will go into an infinite recursive loop once the page is saved. I'm filing this as a security task because it's not possible to recover from this without manually editing the database or patching MediaWiki.

The stack trace roughly is:

#230 /home/km/gerrit/mediawiki/core/includes/title/MediaWikiTitleCodec.php(464): Title::newMainPage()
#231 /home/km/gerrit/mediawiki/core/includes/Title.php(3049): MediaWikiTitleCodec->splitTitleString()
#232 /home/km/gerrit/mediawiki/core/includes/Title.php(457): Title->secureAndSplit()
#233 /home/km/gerrit/mediawiki/core/includes/Title.php(405): Title::newFromTextThrow()
#234 /home/km/gerrit/mediawiki/core/includes/Title.php(742): Title::newFromText()
#235 /home/km/gerrit/mediawiki/core/includes/title/MediaWikiTitleCodec.php(464): Title::newMainPage()
#236 /home/km/gerrit/mediawiki/core/includes/Title.php(3049): MediaWikiTitleCodec->splitTitleString()
#237 /home/km/gerrit/mediawiki/core/includes/Title.php(457): Title->secureAndSplit()
#238 /home/km/gerrit/mediawiki/core/includes/Title.php(405): Title::newFromTextThrow()
#239 /home/km/gerrit/mediawiki/core/includes/Title.php(742): Title::newFromText()
#240 /home/km/gerrit/mediawiki/core/includes/Title.php(1433): Title::newMainPage()

Event Timeline

To reproduce locally, set $wgLocalInterwikis[] = 'wikipedia'; and then change [[MediaWiki:Mainpage]] on-wiki to be wikipedia:.

For reference, this behavior was introduced in T66167: Local interwiki links with no page title should point to the main page / https://gerrit.wikimedia.org/r/c/mediawiki/core/+/127592 (1.24+) with the commit message of:

...
Should MediaWikiTitleCodec depend on Title::newMainPage? Almost certainly
not, but I note that splitTitleString is earmarked for demolition, so I
expect that the confusing dependency-web will be cleaned up in the future.
I also note that MediaWikiTitleCode already uses various static methods of
the Title class.

I suspect it's too late to walk that back now.

because it's not possible to recover from this without manually editing the database or patching MediaWiki.

Not totally true, you could also just remove the local interwiki. But point is, it needs someone with server access to rescue the wiki.

I think there's one more possible loop on language converter wikis, but I need to poke at it further.

I think there's one more possible loop on language converter wikis, but I need to poke at it further.

Ok. I was thinking about deploying the above patch during today's security window, but I can hold off for now.

I'm confident that the patch I posted is correct and closes that hole, if you think it's high priority enough, deploying it now is fine with me

I think the language converter loop exists theoretically (while resolving namespace aliases, it tries to load a message, which recurses back into title parsing), I haven't yet had the chance to figure out what the on-wiki attack looks like and if it might be mitigated at some other layer.

I'm confident that the patch I posted is correct and closes that hole, if you think it's high priority enough, deploying it now is fine with me

I think the language converter loop exists theoretically (while resolving namespace aliases, it tries to load a message, which recurses back into title parsing), I haven't yet had the chance to figure out what the on-wiki attack looks like and if it might be mitigated at some other layer.

Ok, I'll plan to deploy the patch above during the window today (in like an hour) and wait for an updated patch, if necessary.

sbassett added a subscriber: Reedy.

Deployed the Title.php change (and the test). Tracking at T276237. We'll also want to track as a core patch for the next mw security release, though we can probably give @Reedy a bit of a break for a week or two here :)

I think the language converter loop exists theoretically (while resolving namespace aliases, it tries to load a message, which recurses back into title parsing), I haven't yet had the chance to figure out what the on-wiki attack looks like and if it might be mitigated at some other layer.

I poked at this a bit more at the end of December and couldn't actually get it to loop more than once. While the first title might be user-controlled, the messages that recurse back into title parsing are not and can't really be crafted to recurse again/infinitely.

Also, you'd have to exploit it against the first title being parsed since the namespace aliases are cached, but usually the first title parsed is the main page, which we just put a recursion guard around! So altogether I don't think it's exploitable via language converter.

sbassett changed Author Affiliation from N/A to Wikimedia Communities.
sbassett changed Risk Rating from N/A to Low.
Reedy renamed this task from Title::newMainPage() goes into an infinite recursion loop if it points to a local interwiki to CVE-2022-: Title::newMainPage() goes into an infinite recursion loop if it points to a local interwiki.Mar 28 2022, 1:52 PM
Reedy renamed this task from CVE-2022-: Title::newMainPage() goes into an infinite recursion loop if it points to a local interwiki to CVE-2022-28201: Title::newMainPage() goes into an infinite recursion loop if it points to a local interwiki.Mar 30 2022, 6:02 PM

Change 775973 had a related patch set uploaded (by Reedy; author: Legoktm):

[mediawiki/core@REL1_35] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775973 merged by jenkins-bot:

[mediawiki/core@REL1_35] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775978 had a related patch set uploaded (by Reedy; author: Legoktm):

[mediawiki/core@REL1_36] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775984 had a related patch set uploaded (by Reedy; author: Legoktm):

[mediawiki/core@REL1_37] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775978 merged by jenkins-bot:

[mediawiki/core@REL1_36] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775992 had a related patch set uploaded (by Reedy; author: Legoktm):

[mediawiki/core@master] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775984 merged by jenkins-bot:

[mediawiki/core@REL1_37] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775995 had a related patch set uploaded (by Reedy; author: Legoktm):

[mediawiki/core@REL1_38] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775995 merged by jenkins-bot:

[mediawiki/core@REL1_38] SECURITY: Add recursion guard to Title::newMainPage()

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

Change 775992 merged by jenkins-bot:

[mediawiki/core@master] SECURITY: Add recursion guard to Title::newMainPage()

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

Reedy changed the visibility from "Custom Policy" to "Public (No Login Required)".Mar 31 2022, 11:05 PM
Reedy changed the edit policy from "Custom Policy" to "All Users".