Ya hate to see it. But it happens.
Working for a security company, even though I may not be in the trenches with the fine folks who work the security and vulnerability detail, not a week goes by that I don’t hear about some data breach somewhere. Yet another database hacked and leaked. Yet another batch of passwords exposed to the wild. Yet another this and yet another that.
In the dark ages of the internet, it was pretty standard practice: setup a database, and to register a user you ask for a username and a password, and you called it a day. Some people didn’t look too far beyond this, and they’d foolishly store something as sensitive as a password in plain text, and some would (and STILL DO) use woefully outdated info sec practices such as MD5 and SHA1 one way hashing algorithms in a vein attempt to obfuscate someone’s password.
Let me get this out of the way before we continue any further: to the folk still using MD5/SHA1; immediately stop and do pretty much anything else. But, look, at it’s core I can understand why being told to do so might sound jarring. It’s true, it’s impossible to reverse an MD5 and SHA1 hash. It is absolutely impossible. What isn’t impossible though, is to setup a password guessing farm powered by really affordable but powerful GPU’s and CPU’s that can take a crack at millions of guesses per second powered by what is called a “rainbow table“.
With that out of the way, let’s continue.
Modern practices of user account and authentication have evolved a lot, but in many ways it’s still the same old problems. We now usually base a user account primarily off of an email and password combo. This frees up an (optional) user name to be anything of the users choosing, and every other field can be safely ignored until later in the application when it might be needed (Think: an address for an e-commerce site). And as for passwords, we now use purposely slow and very strong one way hashing algo’s like BCrypt and Argon2. They’re slow, because it makes that whole GPU guessing farm thing take dramatically longer to crack per single guess and therefore might help discourage a hacker from trying in the first place.
But really, at the end of the day, if your password is “password” or “mittens1995”, there’s nothing else that the software developer can realistically do to prevent a users account from being hacked into quickly and easily by an aforementioned guessing machine, or by some random hax0r just trying out some best guesses on someone they may have a passing knowledge of. What’s worse is that people tend to reuse the same password over and over again for ease of access to their favorite websites.
As a user, you have some options available to make this part a lot harder, with password managers with built in password generators, you can be sure that the passwords you do use have no real connection to you as a person, which can effectively neuter the data collection of clever social engineers pre-filling their rainbow tables with keywords based on you and your interests. But I challenge a particular mode of thought? namely:
Should you even TRUST a random website with a password of yours, at all?
And why should you? You don’t know how they’re storing it on their systems. For all you know, it could be in plain text, ready for anybody and their grandma to read it. It’s probably safe to assume that facebook stores your data safely, which is weird given the kinds of personal info they collect on you, but your bank likely uses an ancient, and sadly, easily crackable two-way crypto with some awkwardly exploitable rules (maximum length anyone?). So I’d like to pose an alternate question to developers out there:
Should you even trust YOURSELF (or whoever your working for) to store passwords securely enough that in the event of a possible breach your users data will remain safe?
Sure, we don’t like to think that our perfect little chunk of code can be breached, but everything, including any 3rd party package you work with, or even your server’s built in packages for basic operation, is potentially at risk at all times. And you always need to respect your users data under that assumption. So what can you do about it? How about, just, simply not storing passwords in your database? That’d be a nice start, no?
Some time ago, I read a development philosophy that has stuck with me: User Minimalism. It’s the basic guiding principal to only ask for information when needed, and store only what is required for basic minimal operation of the application at large, and check everything else at the door.
Don’t need a legal name? forget it. Don’t need an address? forget it. Don’t need a phone number? chuck it. Don’t need an avatar? get rid of it. Keep your users information light, and minimal at all times. And if you can help it, why not keep a user’s profile down to simply an email address?
How does going Passwordless work? It may take a few words to lock it down, but it’s really quite simple:
- The Login and Registration form is just an email address field
- On entry if an account doesn’t exist, either create one automatically, or ask to verify that the email is correct and ask for consent to create a new profile.
- Generate an authentication token and send it to that email. Give this token a very short expiration. (30 seconds? 1m 30s? Up to you and how confident you are in your email relay)
- User clicks the link in their email, and voila they’re authenticated. Set your cookie or session or whatever you gotta do at this point.
And.. and yeah that’s about it. Turns out, email is a pretty dang good authentication endpoint. Think about it. They’d need access to someone’s root email account to do anything beyond this. There’s no password recovery, there’s no security questions. Even if they knew a correct email, they simply couldn’t progress.
That said, If a hacker has access to someone’s email, the lid is already blown wide open for any other accounts associated with that email anyways and there’s bigger problems for the user at this point beyond our reasonable control. It doesn’t matter how good your password is on Facebook, if the hacker uses the “Lost Password?” feature on there, it just gets sent to that email anyways without requesting what the old password was. And now the user is locked out of their Facebook. Some good that password did over there huh?
Also as it turns out, email account passwords tend to be the hardest things to get into with untold numbers of man hours spent on locking down the security practices of keeping unwanted people out, and account recovery options available that your app no longer needs to implement. An added bonus here is that it saves you time and tedium from writing your own password and account recovery tools.
Additionally, when there’s no passwords to recover from a database, and the information you collect is minimal and innocent enough, what is there really to attract a hacker to breach your data? Don’t get me wrong, if there’s a plain text private message feature or something of a similar nature implemented then that’s all a hackers dream. But if the data is primarily publicly accessible, then there’s really nothing interesting to breach and leak. Though this is circumstantial, it continues on with the idea of User Minimalism. If you don’t need to store private data of any kind, there’s nothing to attract a hacker, for the effort involved will yield nothing to ransom with or expose if the interesting data stored is already visible.
At the end of the day, the basic message is this: the date and time for storing passwords is long past. We no longer need to do it at large. So let’s stop doing it entirely, and keep our users feeling secure and confident.
PS. I detest that my little WordPress blog wants one at all and I'm tempted to ditch the WP powered forum portion entirely because it encourages peoples to sign up through the WordPress platform to use it (and, I mean, no one uses it anyways).