Page MenuHomePhabricator

Attempting to disable TOTP OATHAuth using a scratch code fails, but still consumes a scratch code
Closed, ResolvedPublicSecurity

Description

Steps to reproduce:

  1. Have 2FA enabled
  2. Log in
  3. Go to Special:Manage_Two-factor_authentication
  4. Use Disable for TOTP
  5. Use a scratch code for the validation

What happens:
Successful disabling is reported
2FA is NOT actually disabled
The scratch code is consumed

What should have happened:
2FA should have been disabled

Security risk: Availability
Users may be locked out of their account without any ability to recover

Was able to replicate this in production on testwiki, also received private user reports of the same problem

Details

Author Affiliation
Wikimedia Communities

Related Objects

Event Timeline

Xaosflux changed Author Affiliation from N/A to Wikimedia Communities.Fri, Apr 26, 12:09 PM
taavi subscribed.

This seems like a regression from https://gerrit.wikimedia.org/r/c/mediawiki/extensions/OATHAuth/+/964988 - using a scratch token updates the key data to mark that as used and the not-great implementation of OATHUserRepository::persist() gives all keys new IDs means that the removeKey call in TOTPDisableForm won't find the key to delete.

Tagging MediaWiki-Platform-Team for code review for a patch that I'm going to upload shortly.

Does this need to stay private? I'm not immediately seeing any ways to abuse this.

It probably doesn't need to be private, as the avenue for triggering the availability problem requires you to already have the secret information for the account that would be impacted

taavi changed the visibility from "Custom Policy" to "Public (No Login Required)".Fri, Apr 26, 1:28 PM
taavi changed the edit policy from "Custom Policy" to "All Users".

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

[mediawiki/extensions/OATHAuth@master] Fix disabling TOTP keys with scratch tokens

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

I'm not familiar with the codebase, so this may be a silly question...

The patch description describes a bug in persist() and how it is being replaced by updateKey() but the old code is still in place because of a dependency from WebAuthn. Does this mean that there still exists a different scenario that exposes this problem when the buggy code is invoked by WebAuthn?

I'm not familiar with the codebase, so this may be a silly question...

The patch description describes a bug in persist() and how it is being replaced by updateKey() but the old code is still in place because of a dependency from WebAuthn. Does this mean that there still exists a different scenario that exposes this problem when the buggy code is invoked by WebAuthn?

Not 100% sure of your questions, however webauthn doesn't support any recovery at all currently (T244348)

sbassett moved this task from Incoming to Watching on the Security-Team board.
sbassett added a subscriber: Reedy.
Xaosflux renamed this task from Attempting to disable OATHAuth using a scratch code fails, but still consumes a scratch code to Attempting to disable TOTP OATHAuth using a scratch code fails, but still consumes a scratch code.Fri, Apr 26, 2:39 PM

Change #1024687 merged by jenkins-bot:

[mediawiki/extensions/OATHAuth@master] Fix disabling TOTP keys with scratch tokens

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

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

[mediawiki/extensions/OATHAuth@REL1_42] Fix disabling TOTP keys with scratch tokens

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

The patch description describes a bug in persist() and how it is being replaced by updateKey() but the old code is still in place because of a dependency from WebAuthn. Does this mean that there still exists a different scenario that exposes this problem when the buggy code is invoked by WebAuthn?

As far as I can see, no, at the moment WebAuthn doesn't seem to be doing anything that would cause this bug to appear. However there is a patch in review that could have introduced similar issues, and I've sent an additional patch (https://gerrit.wikimedia.org/r/c/mediawiki/extensions/WebAuthn/+/1024705) to fix the potentially problematic use of persist() there as well.

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

[mediawiki/extensions/OATHAuth@wmf/1.43.0-wmf.2] Fix disabling TOTP keys with scratch tokens

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

Change #1025174 merged by jenkins-bot:

[mediawiki/extensions/OATHAuth@wmf/1.43.0-wmf.2] Fix disabling TOTP keys with scratch tokens

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

Mentioned in SAL (#wikimedia-operations) [2024-04-29T08:17:59Z] <taavi@deploy1002> Started scap: Backport for [[gerrit:1025174|Fix disabling TOTP keys with scratch tokens (T363548)]]

Mentioned in SAL (#wikimedia-operations) [2024-04-29T08:20:28Z] <taavi@deploy1002> taavi: Backport for [[gerrit:1025174|Fix disabling TOTP keys with scratch tokens (T363548)]] synced to the testservers (https://wikitech.wikimedia.org/wiki/Mwdebug)

Mentioned in SAL (#wikimedia-operations) [2024-04-29T08:33:23Z] <taavi@deploy1002> Finished scap: Backport for [[gerrit:1025174|Fix disabling TOTP keys with scratch tokens (T363548)]] (duration: 15m 27s)

I backported this to 1.43.0-wmf.2 so this is now fixed on Wikimedia sites. Leaving the task open until the backport issue to REL1_42 issue is resolved so this stays visible in the MW-1.42-release board.

sbassett changed the task status from Open to In Progress.Mon, Apr 29, 5:56 PM
sbassett triaged this task as Medium priority.
sbassett awarded a token.

Change #1024713 merged by Majavah:

[mediawiki/extensions/OATHAuth@REL1_42] Fix disabling TOTP keys with scratch tokens

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