Implementing a Password Strength Indicator
Jeremy Allen - Fri, 22 Jun 2018

Passwords are a mostly necessary part of almost all web applications. A lot of research has gone into how applications should deal with passwords, from the UX of password creation, to the storage of passwords. Large password breaches have taught the security industry a lot about the types of passwords people create and how (not) to store passwords. Troy Hunt has published a rather exhaustive article on this topic. This article dives in on one aspect of secure passwords: the UX and UI of password entry, specifically, how to implement a decent password strength checker.

Why a Strength Indicator

If you have not read Troy's article, you are strongly encouraged to do so now before continuing. Or you can take it on faith that, at most, your web application should only be enforcing a minimum password length and no other complexity metrics. If this makes you uncomfortable, welcome to this brave new password world. The short version is, users are not good at passwords. They don't know what they don't know about passwords, but we do know. If your application enforces a bunch of zany requirements, such as forcing them to use arcane magic symbols and perform a seance before your application will accept their password, the chances are quite high that the users will cast the most simple spell possible to defeat your password checker.

User: types in his favorite password 'goats'
Application: NO. Your password must be blah blah blah blah
User: Goats00!
Application: Excellent. Thank you for playing

Did this complexity enforcement increase the security of your web application? Counter-intuitively it probably didn't. It probably decreased your security. It turns out password cracking technology combined with the glut of powerful and inexpensive GPUs can destroy passwords like that in no time. The goal of the password strength indicator is to influence user behavior to help them make a better choice about their password. And, if they really, really just want to use the same bad password, we can't stop them and we don't gain any extra security enforcing complexity requirements.

Implementation

Our password strength indicator will use two primary tools:

Despite the funny name, Have I Been Pwned (HIBP) is a real, and easy to use, API and project. zxcvbn is a Javascript library that gives good heuristics about a given password and also knows about some of the most common password. HIBP lets use (securely!) determine if a candidate password a user is typing has been involved in a breach. These two tools allow the application to inform the user about their password choices and act as a guiding hand, encouraging them towards, but not forcing, good password choices. The research shows that when users know they are making a bad password choice they will often make a better one. Our UI will also give them some hints, without forcing any particular complexity scheme (but we don't tell them that).

Check out our example implementation.

image

In the image above the user entered the password 12345678. Go ahead and try some other common dictionary words. Password are kept secure because only a (hashed) portion of it is sent to HIBP. An attacker will not be able to use anything sent to HIBP to recover the user's password. Have I Been Pwned API

Disclaimer

Disclaimer: No tool is perfect. It is easy to come up with an easy to crack password that does not exist in any breach and the password strength indicator will say is "strong". Also, the UI has some small issues and is meant to be illustrative of how to implement a password strength indicator. The key elements are running the password through zxcvbn and the HIBP API and then presenting that information to the user and giving them guidance on how to improve their password strength. How to implement this will vary for each UI framework.

Source

Also available as a GitHub gist.