In an era where password breaches are all too common, it's easy to be concerned about what companies do with user passwords. Unfortunately, in most cases it's a black-box scenario where we can only guess at what's going on under the hood based on clues like character or length restrictions. Sometimes it's clear when there's a problem (like when "forgot password" emails your password back to you), but other times there isn't any way to know for sure.
That's why we want to part the curtain and explain how Pluralsight handles passwords, especially since in the past we've given people some cause to question our security.
It would be disingenuous to write this post without owning up to our mistakes. Our big one was that we used to email plaintext passwords to some of our new users. It was only for users that created their account by redeeming an offer code, and we did try to create strong randomized passwords... but emailing the password instead of a password reset link was just wrong. So we fixed that.
The other thing that caused concern was that some passwords would cause our site to throw a 500 "hardcore" error. Naturally this led people to ask, "Doesn't Pluralsight allow strong passwords?" The underlying problem was that the .NET framework by default throws an exception for certain inputs (like when it contains the '<' character) because they are "potentially dangerous values" that could be HTML injection. We've since added the appropriate framework exemptions for the password fields so that these types of passwords are no longer a problem.
Looking at Pluralsight from the outside, these warning signs caused some people to wonder about the rest of our security. What's actually going on under the hood?
How We Handle Passwords
We've never stored password data in plaintext. Originally we used SHA-256 hashes with per-user salts. Then last summer, we moved to bcrypt as our default algorithm, and we upgrade old passwords when users sign in (because that's the only time we have the plaintext password to re-hash to the new algorithm). If a better algorithm comes along later, we can likewise upgrade our users to that.
Because we cannot recover passwords, we send password reset links with one-time tokens which expire after a short period.
As far as restrictions go, we require passwords to be at least 8 characters long, and no longer than 128 characters. Why 128? Because it's an arbitrary number (and power of 2) which we felt was sufficiently large to create strong passwords without being so large that it starts impacting things like server memory or network bandwidth. There are always limitations and tradeoffs. After all, does anyone really need the entire text of Moby Dick as their password?
We don't have any requirements around special characters, previously used passwords, or anything like that. It's possible that we might eventually add some additional restrictions, but we also recognize that some password policies have the effect of reducing security instead of increasing it.
As Pluralsight has grown, we've added more developers and broken down our original monolith codebase down into smaller bounded contexts owned by separate teams. One of the upshots is that we have been able to focus on improving our security.
For mobile apps, there is an expectation that once you sign in, you stay signed in. For our Pluralsight apps, we now use a long-lived authorization token for this scenario so that passwords need not be stored on the device. And if typing your password is inconvenient on mobile, we also have an out-of-band authorization option. When you lose or upgrade your device, you can revoke the old one's access from your account settings page.
We have some other ideas too. Adding a password strength meter to our site could be a nice way to encourage users to create stronger passwords without risking policies that unintentionally reduce the attack space. We're also considering blacklisting common bad passwords, like "password" or "12345678". Two-factor authentication has been brought up multiple times. But not all ideas get implemented.
Security is a Gradient
Often times people think about security as being binary: either you are secure or you are not. But the truth is that there are degrees of security, and not everything needs to be the digital equivalent of Fort Knox. Some sites, like banks, need high security because of the value of what they need to protect. Other sites, like simple forums, may have very little value and don't need multi-factor authentication, security questions, and the like.
Similarly, there are usability tradeoffs to consider. How can we make Pluralsight more secure without detracting from the learning experience?
Pluralsight definitely has valuable data to protect for our users: personally identifiable information (PII), subscriptions, learning data, assessment scores, and so forth. So we want our security to be high. We just have to pick and choose which changes to the site add the most value to our customers. We're excited about continuing to make Pluralsight a better experience as well as more secure.