If all accounts have 2FA for a given product, is there any reason why the 2FA box couldn't be on the primary login screen? Is it bad practice to request 2FA code along with username and password on the same screen? Other than 2FA being optional on some products, are there any other reason why 2FA should show up after successful login?
I think you're misinterpreting what actually happens. It's not doing the second factor (SMS code, authenticator app) after login is successful, but simply after one factor (password) has been verified. The state between the two authentication methods is still not logged in.
Your question, then, might be "why not send all factors at once", and instead do a multi-phase approach. There can be several reasons:
- Cost. Sending an SMS code costs money. If you send it out immediately with the password prompt, you'll end up sending many codes for nothing. It can be used as an attack against you by ramping up your service costs.
- Hassle. If I get a 2FA notification in my Authenticator app any time a bored hacker tried randomly brute forcing my password, I'll quickly learn to ignore it. Save it for those attackers who actually have my password.
- Security. By having my login prompt ask for both password and authentication code, I'm giving attackers information about my security settings (e.g. which users have 2FA enabled) they might not have had, and which they can use to focus on more vulnerable accounts.
In most websites, 2FA are optional. The site can only know whether the user needs 2FA after the user enters their username. Additionally, most sites requires successfully authenticating the password as well to display the 2FA box because otherwise an attacker can do an amount enumeration attack and figure out which users have 2FA enabled or not. Also, some sites may allow use to tick "remember me on this device" on the 2FA which will allow you to login without 2FA when using that device.
Also, many sites implements multiple ways to do 2FA, some users might use SMS based 2FA and others use TOTP, the site would only know which type of 2FA to use after the first step, and more importantly for SMS 2FA, it can't know which phone to send the code to until the first step.
If you know that all users of your site must have TOTP 2FA enabled, then there isn't any reason not to display the TOTP field immediately.
I want to answer the question with your exact scenario in mind, something I think others haven't done: A website where all users are required to set up 2FA using Time-based One-time Password (TOTP), à la Authenticator app (I personally prefer Microsoft's over Google's), and not other forms of 2FA.
There is one major reason why asking for the TOTP should be done in a second stage and not in the same screen with the user name and password, and that is that you don't want to ask for the TOTP every single login. Instead, you want to use Risk-based authentication (RBA) and other techniques to determine if the attempted login request has been made from a previously authorised device, and if that device is likely to be used by that user (e.g. a geographical location you've previously seen the user supply a correct TOTP from). If that login is determined to be low risk, you shouldn't ask for a TOTP but be satisfied by the user name and password. That is because the second factor won't come from the TOTP but rather from a cookie you've previously stored in the user's browser after a successful 2FA authentication, along with RBA to enhance the reliability of it (e.g. If the device was hacked and cookies were stolen).
Your website may also have a concept of "this is a public computer" or "remember this device" checkbox to have the user indicate whether he wants TOTP to be skipped on that device next login. So when skipping the TOTP, you're still using two factors: user name and password (something you know) and a cookie (something you have) and if you use RBA to check stuff like geographic location then it's a third factor (something you are) without ever inconveniencing the user to enter that darn TOTP they hate to punch in.
You can make a decision on whether to ask for a TOTP only after you've identified the user, so the user name and password step just be separate from the TOTP step.
It is generally considered good practice to submit and check all credentials in one go. If you only ask for the second factor after validating the first, you’re leaking information about the validity of that password, which can then be tested with the username in other, non-2FA web sites.
Please also note that “factor” means one of the following: 1 something you know (eg a password, PIN, memorable word, etc) 2 something you possess (often a device registered to your account that generates codes unique to that device, or a smartphone or an ID card) 3 something you are (fingerprints, faces, 3-d maps of vein structures in your hand, retina patterns, whatever)
Sending passwords through different channels is all “something you know”, but having a one-time password sent to your phone is “something you possess” (the phone). Unless you’ve been SIM-swapped or the victims of an SS7 attack, of course, for which case having a unique password for every account is still a good idea...
The answers so far make good points, I just wanted to add that there are well-regarded sites that do 2FA differently than how you describe.
Notably, Google will ask you for your email, password and 2FA on individual pages, making the UI much cleaner and smoother.
One approach I particularly like is from the Internet Banking for one local bank (george.csas.cz). It asks for client number first, after getting the client number, it sends you SMS (if you authenticate through SMS) than shows one dialog for password + 2FA (2FA is not optional so this is displayed always). This has the advantage that the SMS usually arrives while you are typing the password, so you don't have to wait for it, making the user experience a bit smoother. This consideration is obviously less relevant for 2FA via Google Authenticator or similar.
As others have pointed out is likely most sites choose to perform 2 separate stages, because the 2nd factor is optional, either due to some accounts not needing a second factor or some kind of "remembered device" mechanism.
Again as others have pointed out, many implementations choose to leak information by only challenging for the 2nd factor after the first factor has been accepted/validated.
While it is true that leaking this information is not optimal from a security standpoint, it can be argued that it creates a better user experience: The user knows which check failed (the password or the second factor) and only has to repeat that step.
This may also be helpful for support staff who are assisting a user that has problems with their login, although it should be noted that support staff could be notified of which check failed by another mechanism (for example checking the logs).
A counter to the "ease of use" argument would be the use of password managers since most user who are using a password manager to automatically fill in their password won't "fat finger" the website password.