Page MenuHomePhabricator

CVE-2026-39937: Global vanishing does not remove the user email completely
Closed, ResolvedPublicSecurity

Description

When looking into a question raised by User:Cabayi in my mailbox, I noticed global account vanishing only removes the user email address from the globaluser record, but not from the (many) individual user tables. For example:

[urbanecm@stat1008 ~]$ analytics-mysql centralauth
mysql:research@dbstore1008.eqiad.wmnet [centralauth]> select gu_name, gu_email from globaluser where gu_name='Renamed user 28145919bd97ab8be70d27c2e463c510';
+-----------------------------------------------+----------+
| gu_name                                       | gu_email |
+-----------------------------------------------+----------+
| Renamed user 28145919bd97ab8be70d27c2e463c510 |          |
+-----------------------------------------------+----------+
1 row in set (0.001 sec)

mysql:research@dbstore1008.eqiad.wmnet [centralauth]> ^DBye
[urbanecm@stat1008 ~]$ analytics-mysql jawiki
mysql:research@dbstore1009.eqiad.wmnet [jawiki]> select user_name, user_email from user where user_name='Renamed user 28145919bd97ab8be70d27c2e463c510';
+-----------------------------------------------+----------------------------+
| user_name                                     | user_email                 |
+-----------------------------------------------+----------------------------+
| Renamed user 28145919bd97ab8be70d27c2e463c510 | (REDACTED, CONTAINS USER EMAIL) |
+-----------------------------------------------+----------------------------+
1 row in set (0.001 sec)

mysql:research@dbstore1009.eqiad.wmnet [jawiki]>

This is potentially significant, because we indicate emails are no longer kept. Also, IIRC, the feature was internalized into MediaWiki to be able to meet account deletion defined by Google/Apple.

Event Timeline

Leaking only to shell holders, but..

This is the relevant piece of code from CentralAuth:

$data = [ 'gu_name' => $newname ];
if ( $type === GlobalRenameRequest::VANISH ) {
	// Vanish requests need to remove user's email
	$data[ 'gu_email' ] = '';
}
$dbw->newUpdateQueryBuilder()
	->update( 'globaluser' )
	->set( $data )
	->where( [ 'gu_name' => $oldname ] )
	->caller( __METHOD__ )
	->execute();

GlobalRenameUser::getJob doesn't access $options['type'], so the default parameter in LocalRenameUserJob (used for vanishing as well) is GlobalRenameRequest::RENAME when it should be GlobalRenameRequest::VANISH. That should be sufficient to address this, because then we'll hit the code path that uses User::newSystemUser( $renamedUser->getName(), [ 'steal' => true ] );

GlobalRenameUser::getJob doesn't access $options['type'], so the default parameter in LocalRenameUserJob (used for vanishing as well) is GlobalRenameRequest::RENAME when it should be GlobalRenameRequest::VANISH. That should be sufficient to address this, because then we'll hit the code path that uses User::newSystemUser( $renamedUser->getName(), [ 'steal' => true ] );

Note this has wider effects than email: It also scrubs gu_password and user_password, making the actions irreversible. FWIW, this came up in the context of https://meta.wikimedia.org/wiki/Talk:Account_vanishing#c-Cabayi-20260223143200-Reversal_/_Unvanishing, where the reversibility is being discussed. (No objections towards deploying that though, I just want to make sure those consequences are known/expected in general)

GlobalRenameUser::getJob doesn't access $options['type'], so the default parameter in LocalRenameUserJob (used for vanishing as well) is GlobalRenameRequest::RENAME when it should be GlobalRenameRequest::VANISH. That should be sufficient to address this, because then we'll hit the code path that uses User::newSystemUser( $renamedUser->getName(), [ 'steal' => true ] );

Note this has wider effects than email: It also scrubs gu_password and user_password, making the actions irreversible. FWIW, this came up in the context of https://meta.wikimedia.org/wiki/Talk:Account_vanishing#c-Cabayi-20260223143200-Reversal_/_Unvanishing, where the reversibility is being discussed. (No objections towards deploying that though, I just want to make sure those consequences are known/expected in general)

I think that's OK, since that was already happening on the central wiki?

Are we still ok with the patch from T418122#11640588? It seems reasonable to me. If folks are still ok with this approach for now, we could likely get this deployed during today's security deployment window.

The local password tables are empty on CentralAuth wikis anyway. The first system-user-ification will scrub the password from globaluser; that seems like a good thing from a privacy / data removal rights perspective.

Are we still ok with the patch from T418122#11640588? It seems reasonable to me. If folks are still ok with this approach for now, we could likely get this deployed during today's security deployment window.

Yes, I think we should do it.

This change caused vanished accounts to be labelled as "system users" in the wiki interface, e.g. on Special:UserRights, which was filed as T420848: AccountVanishing is marking endusers as system users. I was quite confused what's happening until I found this task with its security patch.

A few people in that discussion pointed out that we had some ambiguous old decisions about *not* removing passwords from vanished users. I filed T421525: Should vanishing an account remove its password and other login credentials? with a sketch of the history, so that we can once again and finally decide what should happen.

Reedy subscribed.

Any objections for this patch to go through Gerrit?

Any objections for this patch to go through Gerrit?

Not from me.

Change #1267098 had a related patch set uploaded (by Reedy; author: Kosta Harlan):

[mediawiki/extensions/CentralAuth@master] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Change #1267098 merged by jenkins-bot:

[mediawiki/extensions/CentralAuth@master] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Change #1267108 had a related patch set uploaded (by Reedy; author: Kosta Harlan):

[mediawiki/extensions/CentralAuth@REL1_45] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Change #1267110 had a related patch set uploaded (by Reedy; author: Kosta Harlan):

[mediawiki/extensions/CentralAuth@REL1_44] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Change #1267111 had a related patch set uploaded (by Reedy; author: Kosta Harlan):

[mediawiki/extensions/CentralAuth@REL1_43] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Change #1267108 merged by jenkins-bot:

[mediawiki/extensions/CentralAuth@REL1_45] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Change #1267110 merged by jenkins-bot:

[mediawiki/extensions/CentralAuth@REL1_44] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Change #1267111 merged by jenkins-bot:

[mediawiki/extensions/CentralAuth@REL1_43] SECURITY: Forward 'type' option to LocalRenameUserJob for vanishes

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

Mstyles renamed this task from Global vanishing does not remove the user email completely to CVE-2026-39937: Global vanishing does not remove the user email completely.Apr 7 2026, 10:28 PM
Mstyles changed the visibility from "Custom Policy" to "Public (No Login Required)".
Mstyles changed the edit policy from "Custom Policy" to "All Users".
Mstyles claimed this task.