Page MenuHomePhabricator

Cannot switch 2FA method between TOTP and WebAuthn: InvalidArgumentException: User already has a key from a different module enabled (totp)
Closed, ResolvedPublicPRODUCTION ERROR

Description

Steps to replicate the issue:

  • Set up 2FA using TOTP or WebAuthn using Special:Manage Two-factor authentication (e.g. on enwiki)
  • On Special:Manage Two-factor authentication, under "Switch to an alternative method", select "Enable" for the method that was not set up
  • Go through login and 2FA confirmation process
  • Confirm switching method (click button)
  • Go through setup process for new method

What happens?:

An error message is shown:

[c4fa815b-f152-4751-87fd-2e0305ef9bbf] Fatal exception of type "InvalidArgumentException"

image.png (855×122 px, 10 KB)

What should have happened instead?:

The 2FA method should have been switched.

Other information (browser name/version, screenshots, etc.):

I have tried this (including using different WebAuthn keys) on these platforms:

  • Chrome / Chrome OS 126.0.6478.120
  • Firefox 127.0.1 on Debian 12.5
Error
normalized_message
[{reqId}] {exception_url}   InvalidArgumentException: User already has a key from a different module enabled (totp)
exception.trace
from /srv/mediawiki/php-1.43.0-wmf.10/extensions/OATHAuth/src/OATHUserRepository.php(162)
#0 /srv/mediawiki/php-1.43.0-wmf.10/extensions/WebAuthn/src/Authenticator.php(330): MediaWiki\Extension\OATHAuth\OATHUserRepository->createKey(MediaWiki\Extension\OATHAuth\OATHUser, MediaWiki\Extension\WebAuthn\Module\WebAuthn, array, string)
#1 /srv/mediawiki/php-1.43.0-wmf.10/extensions/WebAuthn/src/HTMLForm/WebAuthnAddKeyForm.php(74): MediaWiki\Extension\WebAuthn\Authenticator->continueRegistration(stdClass)
#2 [internal function]: MediaWiki\Extension\WebAuthn\HTMLForm\WebAuthnAddKeyForm->onSubmit(array, MediaWiki\Extension\WebAuthn\HTMLForm\WebAuthnAddKeyForm)
#3 /srv/mediawiki/php-1.43.0-wmf.10/includes/htmlform/HTMLForm.php(792): call_user_func(array, array, MediaWiki\Extension\WebAuthn\HTMLForm\WebAuthnAddKeyForm)
#4 /srv/mediawiki/php-1.43.0-wmf.10/includes/htmlform/HTMLForm.php(673): MediaWiki\HTMLForm\HTMLForm->trySubmit()
#5 /srv/mediawiki/php-1.43.0-wmf.10/includes/htmlform/HTMLForm.php(689): MediaWiki\HTMLForm\HTMLForm->tryAuthorizedSubmit()
#6 /srv/mediawiki/php-1.43.0-wmf.10/extensions/OATHAuth/src/HTMLForm/OATHAuthOOUIHTMLForm.php(81): MediaWiki\HTMLForm\HTMLForm->show()
#7 /srv/mediawiki/php-1.43.0-wmf.10/extensions/OATHAuth/src/Special/OATHManage.php(247): MediaWiki\Extension\OATHAuth\HTMLForm\OATHAuthOOUIHTMLForm->show(NULL)
#8 /srv/mediawiki/php-1.43.0-wmf.10/extensions/OATHAuth/src/Special/OATHManage.php(185): MediaWiki\Extension\OATHAuth\Special\OATHManage->addCustomContent(MediaWiki\Extension\WebAuthn\Module\WebAuthn)
#9 /srv/mediawiki/php-1.43.0-wmf.10/extensions/OATHAuth/src/Special/OATHManage.php(105): MediaWiki\Extension\OATHAuth\Special\OATHManage->addModuleHTML(MediaWiki\Extension\WebAuthn\Module\WebAuthn)
#10 /srv/mediawiki/php-1.43.0-wmf.10/includes/specialpage/SpecialPage.php(719): MediaWiki\Extension\OATHAuth\Special\OATHManage->execute(NULL)
#11 /srv/mediawiki/php-1.43.0-wmf.10/includes/specialpage/SpecialPageFactory.php(1694): MediaWiki\SpecialPage\SpecialPage->run(NULL)
#12 /srv/mediawiki/php-1.43.0-wmf.10/includes/actions/ActionEntryPoint.php(502): MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, MediaWiki\Context\RequestContext)
#13 /srv/mediawiki/php-1.43.0-wmf.10/includes/actions/ActionEntryPoint.php(145): MediaWiki\Actions\ActionEntryPoint->performRequest()
#14 /srv/mediawiki/php-1.43.0-wmf.10/includes/MediaWikiEntryPoint.php(200): MediaWiki\Actions\ActionEntryPoint->execute()
#15 /srv/mediawiki/php-1.43.0-wmf.10/index.php(58): MediaWiki\MediaWikiEntryPoint->run()
#16 /srv/mediawiki/w/index.php(3): require(string)
#17 {main}
Impact
Notes

Event Timeline

I was able to duplicate this error using another account (TolTest), which did not previously have 2FA enabled. I also found that this error occurs when switching between 2FA methods in either way (TOTP to WebAuthn or WebAuthn to TOTP).

Tol renamed this task from Cannot switch 2FA method from TOTP to WebAuthn to Cannot switch 2FA method between TOTP and WebAuthn.Jun 26 2024, 2:57 AM
Tol updated the task description. (Show Details)

Hi @Tol, thanks for taking the time to report this! Please file text as text so text can be searched for; text as an image cannot be searched for. :)

Aklapper renamed this task from Cannot switch 2FA method between TOTP and WebAuthn to Cannot switch 2FA method between TOTP and WebAuthn: InvalidArgumentException: User already has a key from a different module enabled (totp).Jun 26 2024, 9:10 AM
Aklapper updated the task description. (Show Details)
Aklapper changed the subtype of this task from "Bug Report" to "Production Error".
Aklapper set Request URL to https://en.wikipedia.org/wiki/Special:Manage_Two-factor_authentication.
Aklapper set Release Version to 1.43.0-wmf.10.

Hi @Tol, thanks for taking the time to report this! Please file text as text so text can be searched for; text as an image cannot be searched for. :)

Ah; sorry. I didn't realise the purpose of the UUID there. I'll remember this for next time; thanks for letting me know!

pmiazga added subscribers: taavi, pmiazga.

@taavi could you check this issue? Looks like it's related to our previous 2FA work. I'll be happy to review it.

taavi removed taavi as the assignee of this task.Aug 2 2024, 4:30 PM

Please don't assign tasks to people without asking first; I'll try to have a look at this at some point but my time at the moment is rather limited and this is quite low on my list of interests at the moment so I don't want to create the appearance I'm actively working on it.

Error
normalized_message
[{reqId}] {exception_url}   InvalidArgumentException: User already has a key from a different module enabled (webauthn)
FrameLocationCall
from/srv/mediawiki/php-1.44.0-wmf.20/extensions/OATHAuth/src/OATHUserRepository.php(163)
#0/srv/mediawiki/php-1.44.0-wmf.20/extensions/OATHAuth/src/HTMLForm/TOTPEnableForm.php(266)MediaWiki\Extension\OATHAuth\OATHUserRepository->createKey(MediaWiki\Extension\OATHAuth\OATHUser, MediaWiki\Extension\OATHAuth\Module\TOTP, array, string)
#1/srv/mediawiki/php-1.44.0-wmf.20/includes/htmlform/HTMLForm.php(824)MediaWiki\Extension\OATHAuth\HTMLForm\TOTPEnableForm->onSubmit(array, MediaWiki\Extension\OATHAuth\HTMLForm\TOTPEnableForm)
#2/srv/mediawiki/php-1.44.0-wmf.20/includes/htmlform/HTMLForm.php(705)MediaWiki\HTMLForm\HTMLForm->trySubmit()
#3/srv/mediawiki/php-1.44.0-wmf.20/includes/htmlform/HTMLForm.php(721)MediaWiki\HTMLForm\HTMLForm->tryAuthorizedSubmit()
#4/srv/mediawiki/php-1.44.0-wmf.20/extensions/OATHAuth/src/HTMLForm/OATHAuthOOUIHTMLForm.php(81)MediaWiki\HTMLForm\HTMLForm->show()
#5/srv/mediawiki/php-1.44.0-wmf.20/extensions/OATHAuth/src/Special/OATHManage.php(246)MediaWiki\Extension\OATHAuth\HTMLForm\OATHAuthOOUIHTMLForm->show(null)
#6/srv/mediawiki/php-1.44.0-wmf.20/extensions/OATHAuth/src/Special/OATHManage.php(184)MediaWiki\Extension\OATHAuth\Special\OATHManage->addCustomContent(MediaWiki\Extension\OATHAuth\Module\TOTP)
#7/srv/mediawiki/php-1.44.0-wmf.20/extensions/OATHAuth/src/Special/OATHManage.php(102)MediaWiki\Extension\OATHAuth\Special\OATHManage->addModuleHTML(MediaWiki\Extension\OATHAuth\Module\TOTP)
#8/srv/mediawiki/php-1.44.0-wmf.20/includes/specialpage/SpecialPage.php(729)MediaWiki\Extension\OATHAuth\Special\OATHManage->execute(null)
#9/srv/mediawiki/php-1.44.0-wmf.20/includes/specialpage/SpecialPageFactory.php(1737)MediaWiki\SpecialPage\SpecialPage->run(null)
#10/srv/mediawiki/php-1.44.0-wmf.20/includes/actions/ActionEntryPoint.php(503)MediaWiki\SpecialPage\SpecialPageFactory->executePath(string, MediaWiki\Context\RequestContext)
#11/srv/mediawiki/php-1.44.0-wmf.20/includes/actions/ActionEntryPoint.php(145)MediaWiki\Actions\ActionEntryPoint->performRequest()
#12/srv/mediawiki/php-1.44.0-wmf.20/includes/MediaWikiEntryPoint.php(202)MediaWiki\Actions\ActionEntryPoint->execute()
#13/srv/mediawiki/php-1.44.0-wmf.20/index.php(58)MediaWiki\MediaWikiEntryPoint->run()
#14/srv/mediawiki/w/index.php(3)require(string)
#15{main}
Impact
Notes

Change #1133116 had a related patch set uploaded (by Majavah; author: Majavah):

[mediawiki/extensions/WebAuthn@master] Stop trying to disable other modules before enabling WebAuthn

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

Change #1133116 merged by jenkins-bot:

[mediawiki/extensions/WebAuthn@master] Stop trying to disable other modules before enabling WebAuthn

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

Change #1134383 had a related patch set uploaded (by Gergő Tisza; author: Gergő Tisza):

[mediawiki/extensions/OATHAuth@master] [WIP] Fix multi-key handling

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

Change #1134384 had a related patch set uploaded (by Gergő Tisza; author: Gergő Tisza):

[mediawiki/extensions/WebAuthn@master] Fix multi-key handling

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

This still shows up in the logs for 1.45.0-wmf.1. Any chance the six week old patch by Tgr could get a review?

Not really. The tgr work is based on the Taavi patch, which is currently marked as (-2: Proof of concept). It won't be merged if we review it until https://gerrit.wikimedia.org/r/c/mediawiki/extensions/OATHAuth/+/1132632 gets merged. This error is caused because the entire feature of allowing different 2FA methods is missing — not because it's broken. If I remember right, the system allows having multiple 2FA methods only for the same module (like multiple WebAuthn keys only), but it's still missing the possibility of having multiple keys from multiple modules ( WebAuth key and the regular 6-digit code).

Before we can fix this, we need to tackle T242031 first. Another approach would be to prevent this from happening by hiding/blocking the button that allows having multiple keys.

The error is kind of intentional - we could actually remove it and let users add multiple methods by just removing a throw clause, but that would lead to more confusing errors in other workflows. We could replace it with a nicer error page, but we are so close to properly supporting multiple methods now that I don't think it's worth the effort.

Change #1134384 merged by jenkins-bot:

[mediawiki/extensions/WebAuthn@master] Fix multi-key handling

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

We could replace it with a nicer error page, but we are so close to properly supporting multiple methods now that I don't think it's worth the effort.

In hindsight that wasn't great judgement. But now we do have a nicer error page (are throwing an ErrorPageError rather than a generic exception).

Tgr claimed this task.

Change #1190593 had a related patch set uploaded (by Reedy; author: Gergő Tisza):

[mediawiki/extensions/WebAuthn@REL1_44] Fix multi-key handling

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

Change #1190606 had a related patch set uploaded (by Reedy; author: Gergő Tisza):

[mediawiki/extensions/WebAuthn@REL1_43] Fix multi-key handling

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

Change #1190593 merged by Reedy:

[mediawiki/extensions/WebAuthn@REL1_44] Fix multi-key handling

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

Change #1190606 merged by Reedy:

[mediawiki/extensions/WebAuthn@REL1_43] Fix multi-key handling

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