Page MenuHomePhabricator

CVE-2022-41766: On action=rollback the message "alreadyrolled" can leak revision deleted user name
Closed, ResolvedPublicSecurity

Description

  • Create a page with an Rollbacker (but Rollbacker is not Admin)
  • Move the page with MalicousUser (to create a null revision)
  • Revision delete/suppress the user of the null revision
  • Use the rollback from action=history with Rollbacker and the "alreadyrolled" message shows "last edit of MalicousUser" and leak the revdeled user name of the null revision

Good points: The link to action=rollback contains a empty from and does not leak the name.
Bad points: The rollback link is useless, but provided (thats T6433 for move, but the link is also provided for other null revisions like import or protection) and should not be part of this task

Possible a regression from the refactor in https://gerrit.wikimedia.org/r/c/mediawiki/core/+/675236

Event Timeline

mmartorana added a project: Vuln-Infoleak.
mmartorana changed Risk Rating from N/A to Low.

Hi,

I am working on a patch to fix this issue.

mmartorana changed the task status from Open to In Progress.May 9 2022, 4:11 PM
mmartorana triaged this task as Low priority.

I am proposing this patch to fix this issue:

I am proposing this patch to fix this issue:

+1 just based upon the logic alone. I think we'd want to test this a bit more to see if $userFactory->newFromName( $this->context->msg( 'rev-deleted-user' )->escaped() ); has any unintended consequences. At the very least, MediaWiki doesn't seem to have a problem creating a User object that should work fine:

shell.php
>>> $userFactory = \MediaWiki\MediaWikiServices::getInstance()->getUserFactory();
=> MediaWiki\User\UserFactory {#3362}

>>> $revUser = $userFactory->newFromName( RequestContext::getMain()->msg( 'rev-deleted-user' )->escaped() );
=> User {#5855
     +mId: null,
     +mName: "(Username or IP removed)",
     +mActorId: null,
     +mRealName: null,
     +mEmail: null,
     +mTouched: null,
     +mEmailAuthenticated: null,
     +mFrom: "name",
   }

I am proposing this patch to fix this issue:

It seems weird to squeeze a message into a User object like that. If the issue is the alreadyrolled message leaking the username, we should have a separate message like alreadyrolled-deleted that doesn't output the username, and use that when necessary. Probably that needs to be done in RollbackPage though.

The above patch was deployed to wmf.25 and wmf.26 this morning. The patch applied fine and didn't seem to cause any issues within the logs, but likely wouldn't anyways, given the scope of the patch and likely affected users. That being said - if anyone has user-suppress rights on a project and would like to further test, that would be great. This is now being tracked as a deployed patch at T276237 and for the next security release at T311776.

Thanks to @Legoktm and @Krinkle for real-time help with the patch prior to deployment. There are a few cleanup items (spacing, message function, patch subject) that need to be cleaned up prior to release - I'll try to get a refactored patch posted soon. And then as @Legoktm notes above, it might make sense to create a more optimal follow-up patch with a new message, etc.

Refactored patch:


Changelog:

  1. Fixed whitespace issues
  2. Condensed comments, changed to // style
  3. Use plain() instead of escaped() for rev-deleted-user message
  4. Added SECURITY: to patch subject line, removed bug id
  5. Slightly changed patch subject text
  6. Added Bug: to commit message

Should now pass gerrit at the very least.

Patch should be good for REL1_39 and master, but for REL1_35, REL1_37 and REL1_38, an adjusted patch will be needed due to lack of getAuthority().

master / REL1_39 (same, just added Change-Id)

REL1_38 / REL1_37 (swapped getAuthority() for $user->isAllowedAny(...))

for REL1_35 I need to test, but I *think* it's not present. I think it was introduced in https://gerrit.wikimedia.org/r/c/mediawiki/core/+/675236 which is 1.37+

Confirmed that REL1_35 (with no patch) is fine.

Screenshot 2022-09-28 at 20-53-34 Action complete - Trunk Test.png (429×1 px, 85 KB)

Reedy renamed this task from On action=rollback the message "alreadyrolled" can leak revision deleted user name to CVE-2022-41766: On action=rollback the message "alreadyrolled" can leak revision deleted user name.Sep 29 2022, 5:29 PM
Reedy added a subscriber: gerritbot.

Change 836896 had a related patch set uploaded (by Reedy; author: Mmartorana):

[mediawiki/core@REL1_37] SECURITY: Hide suppressed users from rollback page error messages

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

Change 836900 had a related patch set uploaded (by Reedy; author: Mmartorana):

[mediawiki/core@REL1_38] SECURITY: Hide suppressed users from rollback page error messages

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

Change 836905 had a related patch set uploaded (by Reedy; author: Mmartorana):

[mediawiki/core@REL1_39] SECURITY: Hide suppressed users from rollback page error messages

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

Change 836910 had a related patch set uploaded (by Reedy; author: Mmartorana):

[mediawiki/core@master] SECURITY: Hide suppressed users from rollback page error messages

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

Change 836896 merged by Reedy:

[mediawiki/core@REL1_37] SECURITY: Hide suppressed users from rollback page error messages

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

Change 836905 merged by jenkins-bot:

[mediawiki/core@REL1_39] SECURITY: Hide suppressed users from rollback page error messages

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

Change 836900 merged by Reedy:

[mediawiki/core@REL1_38] SECURITY: Hide suppressed users from rollback page error messages

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

Change 836910 merged by jenkins-bot:

[mediawiki/core@master] SECURITY: Hide suppressed users from rollback page error messages

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

Reedy changed the visibility from "Custom Policy" to "Public (No Login Required)".Nov 1 2022, 6:07 PM
Reedy changed the edit policy from "Custom Policy" to "All Users".