Token Authentication alone not possible with 2FA enabled?

I’ve designed my app to allow the user to choose from several authentication and verification methods:

  1. Email + password
  2. Email + emailed token (accounts-passwordless)
  3. Email + authenticator app (accounts-2fa)
  4. Email + WebAuthn API

They can choose to enable one or more of these methods. When logging in, if multiple authentication methods were setup for the user account, the user is prompted to choose one. Every method works great on its own if only 1 is configured. However, if the user configures both accounts-passwordless and accounts-2fa, and selects accounts-passwordless as the method they wish to use for a given session, Meteor.passwordlessLoginWithToken() does not allow them to log in using the token alone, it throws an error “2FA code must be informed” (as per the docs)

Is there some way to allow the user to login using accounts-passwordless alone even when accounts-2fa is enabled for the user? It’s overkill to have the user enter: email + password + token-from-email + token-from-authenticator-app.

1 Like

I suspect this is a security choice. If your user has 2FA enabled, but you give users the choice to login passwordless, an attacker will just choose that and bipass the 2FA entirely.

I’d be interested in what happens if your user enables authn + 2FA, because those should be usable separately

What I’m wanting to do is allow the user choices and flexibility. A user might want to enable passwordless as a backup to their 2FA, so if they lose their phone (which has the authenticator app), they can still login using passwordless. But given that having 2FA enabled always forces its use, they wouldn’t be able to log into my app if they lose their phone.

Yes, 2FA offers stronger protection than passwordless via email, which itself offers better protection than a password alone, but plenty of apps & sites are perfectly fine with using passwordless alone. I don’t see the point of forcing 2FA on top of passwordless.

BTW, what I’m trying to setup is exactly how Stripe does its MFA:

Same for MongoDB Atlas MFA:

There must be a mechanism to reset 2fa based on an initial reference (which in your case seems to be email). In our user flow, resetting 2fa will remove the 2fa requirements, login the user, and redirect the user to setting up a new 2fa.

Although I admit that there are routes that are redundant to 2fa e.g. passkeys which are 2fa by themselves.

@rjdavid I may have misunderstood your response, but if the user loses access to their 2FA authenticator and you allow them to reset 2FA by authenticating via password alone, doesn’t that defeat the whole purpose of 2FA? In your workflow, how do you authenticate the user to allow them to reset an unavailable 2FA authenticator?

I am not sure where you infer this from my post above.

In our case, the 2FA can be reset through SMS with the consideration that the phone is another factor (a thing that the user owns) and mobile number is the main reference for our user account

As I mentioned above, your user reference is an email address, so if I were in your case, I would use email as a way to reset the 2FA of the account.

Understood, however, that outlines my problem. I’m unable to use accounts-passwordless via email to login the user to reset their 2FA because once the user has registered an authenticator using accounts-2fa, accounts-passwordless then forces the use of 2FA to authenticate. Instead, they should operate independently of each other.

My preference is to use Meteor’s own packages directly, but the issue I’ve outlined might force me to look for an external option. Also, the recommendation now for a couple of years has been to not use SMS as means to verify authentication because of the inherent vulnerabilities.

It looks like this is by design in the meteor package. The rational appears to be that passwordless replaces the password, not the 2FA code

Reading back over your original message:

email + password + token-from-email + token-from-authenticator-app.

It would be email + password + token from authenticator or email + token from email + token from authenticator - it shouldn’t require all 4, but should require all 3.

If you think it shouldn’t be the case, open an issue on the repo.

I think this is a situation where meteor’s “easy to use” gets in the way of “I want to customise it” - would be really nice if these packages just exposed the necessary functionality without necessarily modifying login behaviour unless you opted in.

@znewsham, thanks. I’ll open an issue.

That is indeed the case. Because if someone got a hold of that link (social engineering or brute force), then the 2FA is meant to be the protection.

In my opinion, it’s poor design and creates a poor user experience if there is no secure, alternate backup authentication method available to users who choose to use an Authenticator App as a 2FA method (because phones are easily lost or broken, and some Authenticator Apps (e.g. Google Authenticator) require you to have the old phone to transfer the accounts to the new phone). I believe those methods include:

  • A hardware security key with verification enabled (PIN or biometric)
  • Recovery Codes provided at 2FA registration (safely stored, preferably offline)
  • Passkeys (once they become more readily available)
  • An emailed, short-duration TOTP (Time-based One-Time Password)
  • Push-based notification to a sister app (not common)

Did I miss any? (SMS is currently not recommended for authentication verification because of its multiple vulnerabilities and how easily SMS can be hacked.)

Currently, Meteor provides direct support for only one of the 5 methods listed above (accounts-passwordless). Unfortunately, the design of that package prevents it from being used as a backup authentication method to accounts-2fa. My preference would be to make has2faEnabled an optional check as I’ve suggested in Feature Request #12512.

As designers and developers, if we want to promote the widespread adoption of secure means of authentication, simply being secure isn’t enough. It also has to be easy and convenient for anyone to use.

Just ran into this interesting means of 2FA-secured-account recovery that Rollbar uses should your authentication device become unavailable:

If you are a paying customer, we can make two small charges (less than $1 US) to your credit card. If you can tell us the amount of those charges, then we will disable 2FA and immediately reverse the charges.

That sounds like it’s secure enough, but there’d be much less of a hassle if a secondary backup means of authentication was instead available.