Dear all,
We are in the process of implementing 2 factor authentication in our web
application.
We already have some code written [1], reviewed and which seems to be fine from a
code point of view, however there seems to be still some discussion as to the
approach we should take from a logic/design perspective.
I will here try to summarize the different approach possible with pros and cons.
/!\ summary might be a little long :)
1) Ask for password+2fa token
Login page:
___________________________________________________
| |
| Login: [____________________] |
| |
| Password + 2 fa: [____________________] |
| |
|___________________________________________________|
Mechanism:
Application send login and password + 2 fa to the server that allows or deny
the login.
+ This is the current approach we have on the systems
+ A single request sent to the server
+ Simple
+ Attackers have no way to know if someone activated 2 fa or not
- Confusing for user that do not have or do not know about 2 factor
authentication
- No possibility to know what is wrong (Missing 2fa, wrong password or clock
skew too large?)
2) Ask for password and 2fa
Login page:
___________________________________________________
| |
| Login: [____________________] |
| |
| Password: [____________________] |
| |
| 2 factor: [____________________] |
| |
|___________________________________________________|
Mechanism:
Application send login and password and 2 fa to the server that allows or deny
the login.
+ Still similar to the current approach we have (can be made to mimic 1))
+ Still only 1 request send to the server
- Still confusing for the user that do not know / do not have 2 fa
- Still no possibility to know if you set up 2 fa and forgot about it or
misstyped your password or the 2 fa system is broken (clock skew too big)
3) Ask for password, validate, then ask for 2 fa is set up
Login page:
___________________________________________________
| |
| Login: [____________________] |
| |
| Password: [____________________] |
| |
|___________________________________________________|
Then:
___________________________________________________
| |
| This account has 2fa activated: |
| |
| 2 factor: [____________________] |
| |
|___________________________________________________|
Mechanism:
Application send login and password to the server that validates them, then
asks for a 2 factor if set.
- At minimum 1 request send to the server, more if 2 fa enabled
+ More user friendly as only the person with 2 fa enabled will have the 2 fa
token requested
+ You are able to know if you misstyped your password (which is also a -, see
below).
+ Attackers can brute force password, after that they might (or not) be blocked
by the requirement of 2fa.
4) Ask for password, check if user has 2 fa, ask for token, then validate.
Login page: see 3.1
Mechanism:
Application sends login and password to the server that checks if the user has
enabled 2 fa, if not authenticate user w/ login and password. If 2 fa enabled,
request 2 fa token and authenticate user w/ login, password and 2 fa token.
- At minimum 1 request send to the server, more if 2 fa enabled
+ More user friendly as only the person with 2 fa enabled will have the 2 fa
token requested
+ You are able to know if you misstyped your password (which is also a -, see
below).
- Attackers are able to know if you have 2 fa set up or not, and thus can
target users that do not have it enabled.
5) Application knows if user has 2 fa enabled or not.
Login page:
___________________________________________________
| |
| Login: [____________________] |
|___________________________________________________|
Then:
___________________________________________________
| |
| |
| Password: [____________________] |
| |
| This account has 2fa activated: |
| |
| 2 factor: [____________________] |
| |
|___________________________________________________|
Mechanism:
The application has its own login/password to connect to FAS and retrieve the
information whether the user has 2 fa enabled or not.
+ User friendly
- Attacker directly knows if user has 2 fa enabled or not
- 2 requests sent to the server (always)
- Application has login/password to FAS
- You are not able to know why your login failed (unless we make the server say
so)
I think this summarize the different approach available.
There is a separate issue that we will need to decide upon as well as some
point, regarding the order in which we check a user is authenticated (wrt
session_id), but this is a separate issue for the moment.
So which way do we decide to go?
Cheers,
Pierre