Scenario: Password guessing attacks are happening on your website. The attacker is performing password spraying: he tries a single password for a user, and if it fails, he moves on to the next user. The attacker is also changing his IP address, including the use of IP addresses that are geolocated where many legitimate users come from.
Because of the attacker’s tactics, blocking IP addresses and account lockouts won’t work. You also work for a business that is very sensitive to security controls that impact usability. Captchas, two-factor authentication, and stronger password security policies are rejected by the business.
What can you do?
This blog is about a security control that largely prevents these type of password guessing attacks at minimal usability impact. We call it One-Time Two Factor Authentication (OT2FA). It’s a simple idea derived from a number of sources, including:
⦁ Revisiting Defenses Against Large-Scale Online Password Guessing Attacks by Mansour Alsaleh, Mohammad Mannan, and P.C. van Oorschot.
⦁ Securing Passwords Against Dictionary Attacks by Benny Pinkas and Tomas Sander.
⦁ Enhanced Authentication In Online Banking by Gregory D. Williamson.
OT2FA should not be considered new, as it has strong similarities to what companies like Google and Lastpass are doing (though their implementation details are unpublished). However too many websites are doing alternatives that are both less secure and less user friendly.
One-Time Two Factor Authentication
Two-factor authentication (2FA) is an effective security control for preventing password guessing attacks, but it comes at a large usability impact: users don’t like be challenged for a one-time secret code every time they login. Businesses that are trying to acquire new users to win market share are averse to security controls that annoy users.
But what if one could get close to the security of 2FA with little usability impact? This is what OT2FA aims to accomplish.
The idea is simple: the first time a user logs in from a new user agent (i.e. browser or client software), require them to prove their identity via two-factors: their password, and a secret code that is emailed or SMSed to them (note: email is preferable as SMS security is known to be weak). When the user succeeds in proving the identity, provide a digitally signed token, such as a JWT, back to the user agent: “User X signed in from this device before.” Instead of the actual user name, something like a UUID should be used for the identity, which is tied to the username inside the server database. The token, called a OT2FA token, serves the purpose of marking that user agent trusted for that user. For web browsers, it is particularly convenient to store it in a cookie.
The next time that same user logs in from that user agent, they only need to provide the username and password, and the OT2FA token is sent up transparently to the user as the second factor proof of identity. The server authenticates the user by verifying the username and password are correct, the digital signature on the OT2FA token is valid, and the identity of the user in the OT2FA token maps to the username provided. If all are correct, access is granted without requiring a 2FA challenge from the user. In other words, the second factor challenge to the user happens only the first time he logs in from a particular user agent, and then the user never sees the second factor challenge on that user agent again. Hence the name: One-Time Two Factor Authentication.
This protection is not perfect, but it is a huge improvement in security at little impact to the user. The main thing is that it stops the large scale password guessing attacks: an attacker can only succeed against a user if he not only knows the username and password, but he also can crack the second factor or somehow get the user’s OT2FA token. If we make the assumption that no attacker is going to collect a large number of user OT2FA tokens (discussed further in the Potential Concerns section below), then we would believe that we have stopped the large scale password guessing attacks.
For emphasis, OT2FA is designed only to prevent password guessing attacks against users. There is no need to challenge the user for a second factor when they sign up for an account – new users should get an OT2FA token by default.
Below, we will discuss enhancements and then potential security concerns, but let’s first review where we are. In the context of password guessing attacks, Username/password-only is low security, but very usable. Two factor authentication is high security, but scores low on the usability scale. OT2FA is not as secure as 2FA nor as user-friendly as Username/password-only, but is not bad in either category, and could arguably considered good in both. Therefore OT2FA is a realistic security option for websites built with a strong emphasis on usability.
There are a many directions that one can go to enhance this idea.
For example, by including a unique identifier for each OT2FA token and storing the corresponding value in the database, you can give users the option to revoke OT2FA tokens living on trusted devices / user agents that should no longer be trusted for that user. So although you cannot make the OT2FA token go away, you can enforce on the server side that the specific OT2FA token being sent up is one that the user has not revoked. Some subtleties are discussed in Footnote 1 at the bottom.
Alternatively to maintaining server side state for revocation purposes, one could expire the OT2FA token. Indeed, many implementations (gmail, Lastpass, Azure DevOps, etc…) do this with a fixed expiry, and ask the user for a new 2FA challenge on a regular basis. The problem with expiring the token after a fixed interval is that it no longer meets the “one time” requirement for this design.
A more user-friendly approach to fixed token expiry is to set an initial expiry, but generate a new token with extended expiry each time the user returns. This mimics how “remember me” functionality is often implemented. If a user’s OT2FA token becomes known to an attacker, the user’s only defence then is his password, which needs to be strong enough to prevent the attacker from getting in until the compromised OT2FA token expires. Although less than ideal, attackers are largely limited in the number of accounts they can go after assuming that there is no mass OT2FA token leakage.
Another direction is that OT2FA can be combined with (temporary) account lockout. Different failed password attempts thresholds can be allowed depending upon whether or not a valid OT2FA token is present. For example, one can impose a temporary lockout when the OT2FA token is not present, but still allow logins when the OT2FA token is present – provided that the second (higher) threshold for failed password attempts is not reached. This allows legitimate users, coming from trusted user agents, in easily while preventing hackers from getting in at the same time. It also mitigates the risk of an attacker trying to lock out a legitimate user from his account.
Another idea is allowing more than one user to login from a user agents for shared devices/computers. However there is a risk of over-engineering the implementation for limited benefit.
One can also consider a number of options to rolling this out smoothly, so it becomes as transparent as possible when the technology is first adopted by a company to their existing user base. There are many approaches for that, which would be too much of a tangent to expound upon here.
Aside: Clarification on Tokens
OT2FA tokens should not be confused with session ids or session tokens.
Session ids/tokens are high value and relatively short lived. If an attacker captures a session token, he then can hijack the victim’s account.
OT2FA tokens are long-lived tokens and are insufficient for hijacking an account. OT2FA tokens serve one purpose: to limit the ability of a hacker to perform password guessing attacks on user accounts.
The implementation may leak the validity of the password: The most straightforward way of implementing this is to only challenge for the second factor after the the username and password are confirmed. Note that if it is not implemented this way, then the user would (under some implementation assumptions) get notified every time somebody malicious tries an incorrect password for that user, which would be annoying and a cause of unnecessary stress to the user.
The fact that the validity of the password is leaked is not necessarily a bad thing. In fact, depending upon the wording of the email/SMS with the 2nd factor code, it may be a good thing because it alerts the user that there is good reason to change your password. For example, a notice like:
“A new device has attempted to login to your account! If this is you, please click this link to prove your identity.
“If this was not you, then it means that somebody has your password. Don’t panic: we have protected access to your account. However, we recommend that you change your password to prevent this person from continuing to attempt to access your account.”
Remark: The academic research papers mentioned above are more sophisticated than OT2FA, and attempt to hide the validity of the password (See Section 4 of Pinkas and Sander paper). But they do so using captchas, which we consider a no-no for usability and accessibility reasons. Not to mention that machines seem to be better than humans at captchas nowadays, which defeats the whole point of the technology.
Brute forcing the second factor: When a hacker gets the username and password correct, he can then focus his attention on brute forcing the second factor. This is only practical for the attacker if the second factor is brute force-able (for example, a 6-letter code), in which case it needs to be prevented in some way. For example, for too many wrong second factor guesses, impose a temporary account lockout for devices that do not have a valid OT2FA token for that user. The length of the time for locking the account should be dependent upon the the time to brute force the second factor challenge, and the user should be notified of the lockout via email or SMS.
Private browsing: For those who use private/incognito browsing, they may be forced to do 2FA every time because the OT2FA token does not persist on the client device. Allowing security and privacy conscious individuals to opt-out is one compensating control to address this.
Public/shared computers: You would not want to store the OT2FA token on a shared computer, because this would allow a hacker to capture it and then brute force the password without the second factor challenge. The first defence is to allow the user to click “shared computer” upon login, which will prevent the token from being stored on it. Having a revocation mechanism (see enhancements section) is a second defence.
Stolen OT2FA token: One way to reduce the risk of cookie theft is to make cookies httpOnly. But this alone cannot be relied upon, since there are a number of ways cookies may leak – not to mention that you might not even be using cookies for storing the token.
If the OT2FA token is stolen, it reduces to the security of password-only for that user – assuming the attacker knows to whom the token belongs. Having a revocation mechanism (as described above) is a compensating control.
Mass OT2FA token leakage: If there is mass token theft, then the security reduces to password-only under the assumption that the attacker can somehow map each token to each username. Usernames should not be put in tokens, instead unique identifiers should be stored there that are mapped to the user via the database. If the attacker is able to brute force a large number of these, it implies that the attacker not only has the tokens but also the map between the token and the user. This is a bad situation, and it requires a serious response from the owners of the website. The recommended action is to roll the key that is used for signing the OT2FA token, which means each user has to perform the OT2FA on each of their user agents again.
User loses access to email: If the user loses access to the email address that the second factor authentication requests is sent to, then he cannot add a new user agent as trusted. However, if the user has one already trusted user agent, he can use that one to update his email address on the system, thus working around the problem. When a user’s email address is changed, an email should be sent to the previous address to make sure this did not happen maliciously. There are other controls that can be added to reduce the risk of a hacker who succeeding in defeating the OT2FA from locking out a user from his account.
Is this the same as OWASP page on device cookies? No. It is similar, but the OWASP description gives out device cookies upon valid username/password without requiring the second factor authentication. As mentioned on the OWASP page, it does not stop password spraying attacks like OT2FA does. It also cites the source as Marc Heuse and Alec Muffett, whose discussions on the topic came years after the research cited at the top of this blog.
Is it just risk based authentication? Risk based authentication was first described in Enhanced Authentication In Online Banking by Gregory D. Williamson in 2006, which we cited at the beginning. The document recommends a number of ideas for enhance security, such as:
“Machine Authentication, or PC fingerprinting, is a developing and widely used form of authentication (FFIEC, 2005). This type of authentication uses the customer’s computer as a second form of authentication (PassMark Security, n.d.). Machine authentication is the process of gathering information about the customer’s computer, such as serial numbers, MAC addresses of parts in the computer, system configuration information, and other identifying information that is unique to each machine. A profile is then built for the user and the machine. The profile is captured and stored on the machine for future use by the authentication system (PassMark Security, n.d.). Once the PC fingerprint is gathered, the system knows what machine attributes should be present when the user attempts to access their online bank account (Entrust, 2005). This type of authentication usually requires the user to register the machine at first sign on. If a customer logs in from another computer the system will know to further scrutinize the login attempt. At this point the system can prompt for additional authentication, such as out of band authentication or shared secret questions.”
The concepts here are very similar to the description of OT2FA except they use device fingerprinting instead of digital signatures to identify devices. Indeed, if one Googles for risk based authentication, many websites (example) talk about device fingerprints without mentioning the concept of digital signatures.
Device fingerprints are less preferable than digital signatures. Through reverse engineering, one is able to determine what device properties are used for the fingerprint. Depending upon exact details, this could potentially be used by a hacker to brute force the fingerprint of a victim once he knows the password. In contrast, brute forcing a cryptographic digital signature is not practical assuming that the crypto is done correctly.
In general, OT2FA is a special case of risk based authentication. It is a particularly simple and strong way of implementing the concept.
When security does not have an adequate answer, we often transfer the burden to the user. Putting too much burden on the user is bad security practice, as it violates the important security principle of pyschological acceptability.
In regard to login security, complex passwords, password rotation, captchas, 2FA, etc… are all poor solutions for a general audience due to the burden they put on users. Users resoundingly reject these ideas and technologies for day-to-day online activities, so something better is needed.
OT2FA is a practical tradeoff between security and usability. It offers much stronger than username/password-only security at very little usability impact. It can also fairly easily be implemented by any organisation. Most importantly, it is a realistic/practical solution for stopping large scale password guessing attacks without significantly burdening users.
Footnote 1: If one takes the unique identifier in the OT2FA token for revocation purposes approach, the use of server side persistent storage can change the whole implementation: rather than using digital signatures on the tokens, instead store a copy of each non-revoked token for each user on server side persistent storage. When a user logs in with a OT2FA token, a simple verification that that token is in the server side database for that user takes the place of any digital signature check. The major downside of this approach is that it requires more storage: one token for each device for each user, and any user could potentially generate a large number of them for himself using automated means. If this is considered a threat, then obvious mitigating controls can be put in place.
The author would like to thank Dharshin De Silva for feedback on a preliminary version of this document.