Hacker News new | ask | show | jobs
by jve 1368 days ago
> leak whether or not a password is correct

Errm, could you elaborate what is the issue here?

2 comments

tl;dr: The code should verify the user's second factor before the user's password.

Consider this, scenario A:

1. When attacker enters a username and bad password. then they receive a bad password error.

2. When attacker enters a username and good password, then they receive a 2FA prompt.

And then scenario B:

1. When attacker enters a username and bad password, then they receive a 2FA prompt.

2. When attacker enters a username and good password, then they receive a 2FA prompt.

In scenario A, the website leaks password validity to the attacker. In the case of a brute force attack, the attacker can use the 2FA prompt as a signal that they found a good password. Scenario B does not leak that information, because the second factor was wrong or missing.

More concretely, this pseudo-code:

    if user.authenticate_with_password(password)
      if user.authenticate_with_second_factor(code)
        # ...
      else
        raise InvalidSecondFactorError
      end
    else
      raise InvalidPasswordError
    end
Should instead be this pseudo-code:

    if user.authenticate_with_second_factor(code)
      if user.authenticate_with_password(password)
        # ...
      else
        raise InvalidPasswordError
      end
    else
      raise InvalidSecondFactorError
    end
Hope that makes sense. :)
But which 2FA prompt should they receive?

If MFA can be configured using myriad choices, should a user be prompted to "Insert security key" or "Input security code" or "Send code to your email/SMS" or "Tap YES on your mobile device"?

Since you can't know a priori what the second factor will look like, I'd say it's troublesome to try and present a challenge to every user regardless of their MFA configuration.

Note that this is not universal to all systems.

If your 2FA options all require the user to enter a code, you can simply display a "Please enter your 2FA code" dialog without divulging what kind of 2FA the user has.

How would you prevent someone from spamming a user just by knowing their username? Say, if the 2FA is done by SMS, or email.

An attacker brute-forcing the password could flood the user with multiple messages. The usual response is doing a password reset, but that wouldn't work in your system.

I wonder how systems that use magic links handle this.

> How would you prevent someone from spamming a user just by knowing their username?

Wasn't something like this how Uber got hacked recently? Spamming the target until they clicked "yes" on the 2FA prompt?

Your authentication system should have per-user and per-IP rate limits.
In my pseudo-code example, we're raising a couple errors, InvalidSecondFactorError and InvalidPasswordError. You could imagine there could be finer grained errors, such as TotpRequiredError or HardwareKeyRequiredError, depending on the user's second factors, which could then propagate down to the UI via specific error codes.

The UI could then use these error codes to display the correct prompt, and then resend the request with the appropriate second factor.

You would have to randomize the error when the wrong password is inputed and ensure that for a particular username the returned error is invariant. Else an attacker could infer that when you get a different error you have a correct password.
The bad password error would only be sent if the second factor is valid, though.
It sounds good for stopping attackers, but if I am the real user and enter a bad password it is going to be pretty infuriating spending time troubleshooting the 2FA not working problem that doesn't actually exist. I suspect your service will get a reputation for completely unreliable 2FA which may have unintended consequences.
This can be solved with an error message at the end with something like "You either provided an incorrect password or your 2FA code is incorrect. Check and try again". This still ensures that someone is not able to guess the correct password and reuse it somewhere else where 2FA may not be enabled.
If you input a username and wrong password, in some cases, the service won't prompt you for your 2FA code.

If you input the right username and password, it will then go forward in the flow and prompt you for the 2FA.

I believe parent comment is suggesting the system should prompt for 2FA even if the password was incorrect, so that you can't infer whether you guessed the correct password without also compromising the 2FA method.

This only matters if you re-use passwords, though.

Well, doesn't it also matter if the 2FA method sucks? For example, maybe you can use a SIM swap to get the one-time code, but if you don't have the password, too, then that doesn't help you. In the above scenario, they can figure out whether they have the password or not, and once they do, then use a SIM swap to get the second factor (or whatever), and then they're in. If the login never tells them which factor is bad, it's a bit harder, right?
Correct, ideally it should always prompt for both the MFA and the password before failing