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?
Web-development – Why is 2FA usually done after the correct password has been provided
designprogramming practicesweb-development
Related Solutions
There's a general misconception (and misuse) associated with 403 Forbidden
: it's not supposed to give anything away about what the server thinks about the request. It's specifically designed to say,
I get what you're requesting, but I'm not going handle the request, no matter what you try. So stop trying.
Any UA or client should interpret that to mean that the request will never work, and respond appropriately.
This has implications for clients handling requests on behalf of users: if a user isn't logged in, or mistypes, the client handling the request should reply, "I'm sorry, but I can't do anything" after the first time it gets the 403
and stop handling future requests. Obviously, if you want a user to still be able to request access to their personal information after a failure, this is a user-hostile behavior.
403
is in contrast to 401 Authorization Required
, which does give away that the server will handle the request as long as you pass the correct credentials. This is usually what people think about when they hear 403
.
It's also in contrast with 404 Page Not Found
which, as others pointed out, is designed not only to say "I can't find that page" but to suggest to the client that the server makes no claims of success or failure for future requests.
With 401
and 404
, the server doesn't say anything to the client or UA about how they should proceed: they can keep trying in hopes of getting a different response.
So 404
is the appropriate way to handle a page you don't want to show to everyone, but don't want to give away anything about why you won't show it in certain situations.
Of course, this assumes the client making the request cares for petty RFC flippancy. A malicious enough client isn't going to care about the status code returned except in an incidental manner. One will know it's a hidden user page (or a potential hidden user page) by comparing it to other, known user pages.
That is, let's say your handler is users/*
. If I know users/foo
, users/bar
and users/baaz
work, the server returning a 401
, 403
, or 404
for users/quux
doesn't mean I'm not going to try it, especially if I have reason to believe there is a quux
user. A standard example scenario is Facebook: my profile is private, but my comments on public profiles are not. A malicious client knows I exist even if you return 404
on my profile page.
So status codes aren't for the malicious use cases, they're for the clients playing by the rules. And for those clients, a 401
or a 404
request is most appropriate.
What you need is a true parser. Regular expressions handle lexing, not parsing. That is, they identify tokens within your input stream. Parsing is the context of the tokens, I.E. who goes where and in what order.
The classic parsing tool is yacc/bison. The classic lexer is lex/flex. Since php allows for integrating C code, you can use flex and bison to build your parser, have php call it on the input file/stream, and then get your results.
It will be blazing fast, and far easier to work with once you understand the tools. I suggest reading Lex and Yacc 2nd Ed. from O'Reilly. For an example, I've set up a flex and bison project on github, with a makefile. It is cross compilable for windows if necessary.
It is complex, but as you found out, what you need done is complex. There is a great deal of "stuff" that must be done for a properly working parser, and flex and bison deal with the mechanical bits. Otherwise, you find yourself in the unenviable position of writing code at the same abstraction layer as assembly.
Best Answer
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: