Admin locked out of site after deleting two-factor keys from prefs

Steps to reproduce

  1. Be an admin on an up-to-date Discourse site with one or more two-factor keys enabled, such as security keys and authenticator app.
  2. Be able to log in and out successfully with those two-factor keys.
  3. Ensure that the site setting for enforcing two-factor logins is set to “no”.
  4. Delete all of the two-factor items from your (admin) account using the standard UI tools in the Security tab of the admin’s user profile preferences.
  5. Log out.

Expected behavior

  1. Log in to site with username or password; access granted; or
  2. Log in to site with “email me a link”; access granted.

Actual behavior

Both “expected” scenarios fail with an error message, and login is not allowed:

The selected two-factor method is not enabled for your account.

There is no further way to log in with the admin’s account.


It is worth noting that I am not actually locked out of the site in question; I had another session still active on another computer and was able to go over to that session and re-add a token-based authenticator to get back in. However, had I not had another session I would have been “fully” locked out.

10 Likes

Thanks for reporting this. I’ve had it bookmarked for the past few days, but haven’t got around to testing it yet. I assume that what you’re reporting is correct, but will take a close look at it next week.

4 Likes

I guess this is the bug? We should not allow that if your site setting says that all admins must have 2fa enabled.

I think you are not fully locked out, you can use the console to recover now, but we should not make it easy for you to create a pathological situation.

I’m not quite sure that’s the right logic? I didn’t have enforce second factor on anything but the default value of “no” and it’s not really safe to assume that every installation has more than one admin account. It seems that once the 2FA keys are removed from the profile, some other flag is not being removed somewhere…

I think you are not fully locked out, you can use the console to recover now

I suppose this is a valid emergency workaround although it may be beyond the skills of an admin who does not also manage their server and they might have to track down a sysadmin.

4 Likes

I’m wondering if the recovery codes were left alone. Can you try entering one of those?

1 Like

@Osama while you are in the code, perhaps:

  • IF user will not be allowed to log in again after deleting this 2fa (last 2fa they have and 2fa is required for account according to trust level settings / admin settings)

  • THEN don’t allow them to delete the last 2fa and display an error.

1 Like

I think I have been hit by the same bug (Discourse version 2.7.10, upgraded today).

I was granted admin rights, and enabled 2fa. Later, I created a second user for myself from a different email to be used solely for admin, and granted that one admin rights.
Then I removed admin rights from my original user, and deleted all 2fa methods. Now my original user gets the error behaviour mentioned by the OP.
I don’t have console access to this server. The site is not enforcing 2fa for admins.

Would somebody please detail what exactly needs to be done at the console to unstick this problem.

BTW the reasons I have done this is that I want to be subject to normal permissions and notifications (or not) for private groups on the site via my normal user, perhaps with mailing list mode active. I don’t need the extra friction of 2fa as an ordinary user.

Of course the admin user can see all, so it is on trust that they don’t snoop unneccesarily. That user can leave all notifications switched off, and not enable mailing list mode.

1 Like

I think you don’t get the opportunity to use recovery codes, because they can only be used via the 2fa login flow?

@sam You tantalisingly say that this problem can be solved via the console, without saying what specifically needs to be done. I’d really appreciate a pointer on how to fix this particular problem.

Is this any help?

2 Likes

I suspect not, as the account already has 2FA disabled, or to be more precise, has removed all 2FA methods from their account (2FA shows as “no” in profile), yet somehow the login is still trying to use 2FA.
That guide is for a user that has 2FA enabled but has lost/forgotten their means to generate a valid token.

SOLUTION: As admin user, visit the locked-out user’s details page, scroll right to the bottom and click the red Impersonate button.
Then in the user preferences, add a 2FA method. (need to have the user’s password to do this)
The 2FA secret has to be given to the locked-out user.
In this case I am both users, so not a difficult task :wink:

1 Like

Nice one. :+1::slightly_smiling_face:

Did that allow you to then successfully remove the 2FA from the user afterwards?

No. Removing the 2FA method left the user locked out again.

Does removing 2FA by pressing the Disable All button behave differently than removing the last 2FA method? I.e. does pressing that remove it without locking you out?

I have been able to reproduce this and find a solution using the console.

The repro is slightly different from how it is described in the first post. Step 2 is crucial, steps 3 and 4 are less important.

  1. Be an admin user on an up-to-date Discourse site with one or more two-factor keys enabled, such as security keys and authenticator app.
  2. Enable backup codes
  3. Be able to log in and out successfully with those two-factor keys.
  4. Ensure that the site setting for enforcing two-factor logins is set to “no”.
  5. Delete all of the two-factor items (authenticators and security keys) from your (admin) account using the standard UI tools in the Security tab of the admin’s user profile preferences.
  6. Log out.

What happens is that if all two factor items have been removed, the backup codes are still present in the database, and two-factor authentication is not seen as disabled upon login.

Since there is no authenticator or security key any more, the user is unable to use the backup codes.

Once all authenticators and keys have been removed, the backup codes cannot even be removed in Profile - Security.

Proposed fix: When the last security item is removed from the user, the backup codes should be removed as well.

Workaround: remove all UserSecondFactor records for this user from the database.

UserSecondFactor.where(user_id: 1).delete_all

12 Likes

Is it possible that there cloud be a fix implemented for this in a newer version of Discourse, I just had this exact thing happened to me today and it was a pain to get my account back.

1 Like

I have the same problem with a user complaining that they can’t log in. This user had 2FA enabled on their account at some point, but later removed it. The error message they get when they try to log in is:

The selected two-factor method is not enabled for your account.

  • From the admin menu, I see that the user’s profile lists “Two-Factor Authentication” as “No”.

  • I don’t have the user’s password to employ this workaround Admin locked out of site after deleting two-factor keys from prefs - #13 by ewblen and even if I did, I don’t myself have any 2FA methods to add there.

  • Since it’s bad form to ask the user for their password, so I tried adding changing their e-mail, or adding a secondary e-mail that I control. However, after clicking “Confirm” on the confirmation e-mail URL, I get this error:

The selected two-factor method is invalid.

… and the e-mail is not changed/added.

  • I don’t have access to the console or database for this Discord installation because it’s “managed”.

Is there anything else I can try? Or is the user locked out of their account forever?

This is terrible.

I don’t have access to the discourse console, because this is a “hosted” discourse instance.

Admins need to be able to clear the 2FA factory from the admin interface, it’s extremely unprofessional to have to ask our users for their passwords.

This is clearly a major bug that needs to be resolved. How can we formally report this and track it’s bugfixing progress?

As an OpenSource project with a hosted discourse instance, I can’t access console or database, I only have the admin interface.

Actually I disagree. When 2FA is disabled, 2FA backup codes should be completely ignored and not matter at all.

By fixing this in the wrong place (when the last 2FA method is removed, remove backup codes), we still have people left that can’t login and just gave up without reporting.

By fixing the actual bug (considering backup codes when 2FA is disabled), we fix this for 100% of the users impacted, immediately, instead if just making sure that this is not continually happening to new users.

Worked for me, the user gave me the password.

You must not disable 2FA directly, you must first:

  • remove all 2FA backup codes
  • triple check all 2FA backup codes are removed
  • only then disable 2FA

Using this method you are actually able to disable 2FA. This is both true for admin users impersonating users to get this fixed, but it is also true for every normal user who just wants to disable 2FA.