2FA login rejected

While trying to login to Meta (using username/password) on my account with 2FA enabled, I’m frequently getting this error:

image

but when I take the login path that starts at Google but ends up at this screen, it works consistently:

image

2 Likes

AH! This one’s weird.

I had an incorrect password saved in my in-browser password manager for my account (deliberately, as I’m the kind of person who tends to do things like that):

image

So on the initial login, I put in the correct password and everything was fine. BUT there seems to be a hidden password field on the “Enter 2FA token” page and Chrome was stuffing the incorrect password back into it, causing the wrong password to be sent with the 2FA token verification.

7 Likes

So the bug is that the password field is checked when it should not be (in your first screenshot)?

… I guess?

Arguably this is a chrome problem - HANDS OFF MY PASSWORD FIELDS… it keeps pulling the (incorrect) password from sync state even though I keep deleting it. :rage:

If there were some way to prevent prevent password managers interfering, that would be good.

It would also be good to show the “full” login form, but I understand the desire to keep the “simplified” flow similar to e.g. AWS 2FA login.

I’m unsure here as to what the “right” answer is.

2 Likes

I feel like there is a flow issue here in our API.

The validate 2fa route should not have passwords or anything, just the token, it should pull the user it found out of the session since it already has it.

At the moment the session controller #create is taking in the 2fa / user and password. Instead we should have a proper #confirm_second_factor route that is in charge of validating 2fa and only takes in the 2fa and pulls the user out of the session.

@featheredtoast what are your thoughts here?

Examining the way that AWS does MFA is an interesting exploration. There’s actually just a single form, containing user/pass/code, and (as long as you have JS on) the user/pass boxes are displayed initially, and when you click “login”, it makes an XHR to /authenticate, which responds with “need a token” (if the user account chosen has MFA enabled), and the login form switches over to the “MFA code” box. Entering that code and clicking the go button submits another XHR back to the same /authenticate endpoint, which gives you the big thumbs up and in you go.

2 Likes

Yeah that is exactly what we are doing here, it just gets mega thwarted by rogue password managers. That said @supermathie was kind of poking himself in the eye here with a bad password for meta.

I guess we got to pick if we go AWS way here or Google/Facebook way of distinct route.

It’s hard to see how our login page works because the form isn’t actually in the page source, while the AWS one is, so I can’t easily identify the difference. Perhaps our sneaky hidden login form, which doesn’t have a 2FA code box, is causing Confusion and Delay? Presumably @supermathie is using the same incorrect password trick for his AWS logins, so something different about how we’re doing it vs AWS is tripping Chrome to be more-than-usually annoying.

As an aside, I noticed a deficiency in our login flow – if you get the password wrong on an MFA-enabled account, you get “incorrect password”, rather than getting bumped to the MFA code box. This means that MFA doesn’t provide any additional brute-force protection, which is… sadness. Sure, rate-limiting prevents effective dictionary attacks, but online dictionary brute-forcing has never been particularly effective, compared to good ol’ credential stuffing.

3 Likes

I am, come to think of it, and it doesn’t get messed up.

You really ought to know by now that if you want a user guaranteed to hit weird unexpected conditions during normal use, give me a call :smiley:

3 Likes

I coded against the same endpoint as it was simpler to implement, and seemed less likely to screw up security if I got that wrong, rather than adding additional state to logging in. I’ll see what amazon is doing differently on their form, and what we can do to prevent password managers from overwriting the form on the second request.

I think this is the same flow that Google’s login uses, where it needs a valid password before it asks for your token, and that hits my personal balance of security vs usability. As an additional measure, we could email the user if someone incorrectly inputs the token n times in a row with a valid password, so at least the user can be informed that their password is known.

6 Likes

I would not bother with this, as it seems so unlikely to be hit. Compare with “login from unusual country or device”, that is a better place to invest effort.

2 Likes

Well that was a trip - seems like the browser password managers at least honor disabled input settings. Fixed here :broccoli:

https://github.com/discourse/discourse/commit/3743e90316613387c7ac43885445df407e5a50e1

I also fixed some of the display logic so only either username/password fields or the 2factor input will be shown after the “login via oauth is disabled” prompt - let me know if it looks good to you @supermathie

5 Likes

This topic was automatically closed after 3 days. New replies are no longer allowed.