A Road to User-friendly Password Validation

Blog / Joshua Asbury / March 6, 2020

Setting the Scene

Some time ago we undertook a project, which was the first project in a while that required user registration. It was also the first project to have a change in programming language and thus use of a new framework. A laundry list of problems to work out emerged, and at the top, picking a password policy. It turns out this was harder than it first seemed.

As an ethical software engineer, striving to protect our client’s users’ privacy as best as possible, I started on the journey of researching password policies and frameworks with two goals: good security, and good user experience. A quick Google search can show many sources of what makes both good and bad passwords[1] so this blog post won’t do that; instead, it will highlight some issues we faced and how we went about striking a balance between security and usability.

A Rule-Based Attempt

As with most software companies the first attempt sometimes needs to be quick and ‘just work’ so everyone is not blocked and can write all the cool stuff, then hopefully that first attempt can be replaced later on down the track. For our first attempt, I coded a simple utility class that, using a loop over the input characters, validated a set of simple rules. This KISS approach was fine to start and at a later point, we replaced this home-grown implementation with Passay—a rule-based password validator library—to ensure better tested and more widely used code; especially when compared to our implementation.

With both of these implementations I went with a common—or at least seemingly at the time—practice of requiring a minimum length and a mix of non-alphanumeric characters; specifically: 8 characters, 1 lowercase letter, 1 uppercase letter, 1 number, and 1 symbol.

This particular combination felt like password requirements turned up to 11 and yet still didn’t prevent the use of all weak passwords, e.g. P@ssword1. This policy also resulted in passwords that were difficult to remember. It was at this point a particular xkcd comic came to mind. While this may only be mildly irritating to some users, for others it will be enough to convince them not to sign up for your app if they were on the fence already. Given passwords weren’t guaranteed to be secure, and we were faced with a very real barrier to user conversion, we wanted to reduce this barrier and improve the policy further.

The clear knee-jerk reaction here, when faced with this issue, was to relax the password validation a little—especially since the tighter policy still allowed weak passwords. An obvious, albeit unsafe, alternative to make the users more accepting of the policy would be to remove almost all the requirements and only require a minimum character count. For exactly one (unreleased) commit in Git, this was our password policy.

A Knight in Shining Armour

In comes zxcvbn to the rescue, which provided us with a significant advantage—no character-based rules. Something like baboon-occupy-sandwich-market suddenly is allowed by the password validator and would hopefully be simple to remember; who wouldn’t want to see a baboon behind a counter at a market selling sandwiches.

Allowing more memorable passwords was obviously important to user experience and would hopefully result in stronger passwords. For the most part, zxcvbn satisfied the security goals as well, with the main exception being that passwords still could be socially engineered. For example, if I had a dog, Lucky, then luckyisagoodboy would not be a very secure password but would score 3/4 in strength on a zxcvbn test; though this is a whole different problem to tackle.

The blog post over at Dropbox is well worth the read, but in my opinion, the key features that still made it the better solution are:

  • Detects passwords created from spatial patterns

    • For example qwER43@! would have a low score
  • Checks for l33t speak
  • Checks against large databases of common passwords
  • Calculates a rating out of 4 which is great for visual feedback via meters

  • Provides basic and easily understood points of feedback for the user to assist in improving their passwords strength

    • For example, "Add another word or two. Uncommon words are better."
  • Has no minimum requirements; complexity determines the strength, not searches for specific characters.

Unfortunately, due to time restrictions, we did not have the capacity to extend our app’s password entry UX to provide anything more than zxcvbn’s feedback on how to make the passwords stronger. We would have liked to create interactive strength meters of the rating, with the simplest being a progress bar with colour gradings.

Looking Back and to the Future

The discovery and use of zxcvbn really helped us deliver a user onboarding experience that provided flexibility for users alongside more secure passwords, particularly when combined with other techniques such as hashing and salting.

Interestingly, taking a look at the account creation space now it seems that fewer companies are using an entropy only solution, with companies like Google omitting a strength meter altogether. Instead, it seems like these companies are opting for a combination between password policies and entropy calculations, requiring adequate strength but also requiring minimum length and a mix of lowercase, uppercase, and/or numbers.

In my opinion, this definitely seems to merge the best of both worlds, as long as the assisting password policy isn’t too strict, and is definitely worth exploring as a next step.

Header image by Matt Duncan from Unsplash.