Want to try it for yourself?
Secure password storage is a challenge for every organization — whether a small startup or a major corporation.
For newly founded startups, a lack of resources may mean initially hiring novice developers who lack the deep expertise in proper password storage. Because authentication is added on rather early in the development process, this can lead to poor password storage practices.
This leads to sub-par implementations that form the base of the application. And of course, the more central a module is for an application, the less inclined the developer will be to change it later on in the project’s lifetime for fear of breaking it.
So the bad authentication implementation is passed along until things finally go south and someone manages to steal your users’ passwords.
Application security best practices are critical in the development stage for preventing system breaches in the first place. But nothing is 100% secure, so you must take measures to protect your users’ passwords.
In this article, we’ll cover the most important password storage best practices.
Database security isn’t strictly a password best practice. Rather, it applies to all the data being stored in your database, and as such, it shouldn’t be overlooked.
If an attacker is unable to access your data in the first place, they won’t have the chance to decrypt it either. So be sure to check out your database vendor’s security best practices too.
Of course, this applies to all your systems, not just your databases. If you’re using a popular container engine like Docker, you’re vulnerable to all the issues Dockers brings with it. So don’t neglect container security, and make sure your systems are being monitored as needed.
Never store passwords in plain text. Always create a hash from them and store the hash instead. In password storage, hashing is superior to encryption since a hash can’t be reversed.
If a user attempts to log in, you can recreate the hash from the password they entered and check if the new hash matches the one you saved at sign up. Nobody with access to the database will be able to read or guess the original password from that hash, not even you or your co-workers. Using a hash also means there is no encryption key that could be stolen.
Not all hash functions are created equal. Some aren’t cryptographically safe, and some are made to be computed quickly — which you want to avoid when hashing a password.
Hash functions that can be computed quickly allow attackers to brute-force many random strings until they find the passwords hidden in the hashes. You have to make them work hard. And while you will have to use those slow functions yourself when hashing the password upon signup or login, you won’t have to use it with millions of random strings.
OWASP recommends using Argon2 to hash passwords. If that’s not available, use bcrypt; and if bcrypt is not available, use scrypt.
Salting a password refers to adding a random string to it before hashing it. This ensures the output hashes of well-known passwords don’t look the same. An attacker might have a table with these passwords and the corresponding hashes, and could simply go through it, checking which have been used by your users. This table might have the hash for the password
password in it, but not the one for
Users also tend to reuse the same password for multiple applications. So if an attacker accessed leaked passwords from multiple popular applications, salting them before hashing will prevent them from being able to compare them.
The salt string will be stored alongside the password string in your database. Modern hashing libraries like Argon2 or bcrypt automatically salt passwords before hashing them.
Peppering your passwords works the same as salting: You add a random string to it before hashing.
The difference between the two is that with peppering, the string is the same for all passwords, but the pepper string isn’t stored alongside the passwords in the database. Instead, you have to store it in the filesystem or in object storage. Anywhere is okay, as long as it’s not stored in the same place as your password database.
Should a hacker manage to access your database, they would still be missing a piece of data, and it would be much more difficult to match your password hashes with the correct passwords.
Though hash functions take some time to do their work, as computer processing speed accelerates, the process is also getting faster. A hash creation that may have taken you a few seconds back when the code was written might take an attacker with a better computer just milliseconds.
To get around this problem, hash functions come with a parameter called “work factor.” By the work factor, the function will do more iterations on your hash, and thus, take longer.
There are two considerations with work factors. On the one hand, you don’t want to make hashing too easy for an attacker, but on the other hand, you don’t want to make it too hard to log in. In general, you should therefore avoid choosing extremely high work factors.
If you upgrade your infrastructure and your servers become more performant, you should also upgrade your work factors so your security benefits from that performance gain too.
It was once considered best practice to force users to change their passwords every few weeks. The idea was to give stolen passwords an expiration date. In practice, however, this only frustrated users and led them to choose simpler, more insecure passwords.
If you’re bound by this outdated practice due to compliance regulations, you won’t be able to get around it. But if there are no external factors requiring you to follow such guidelines, don’t make your users change their passwords. This will ensure better password quality in the long run.
Overall, password length is more important than how complex it is. The longer the password, the more processing time it takes to hack programmatically (years, in some cases). This can be considered a good thing because a user can remember
IonceateahamburgerinLondon much better than
That’s why you shouldn’t require users to use numbers or special characters. Simply let them write down what they want and make sure it’s longer than five characters.
While you shouldn’t require users to use arbitrary complex passwords, checking new passwords against well-known ones in public dictionaries and deny lists is recommended. If a new password matches the content of these sources, inform the user and ensure they don’t use it.
Hackers also rely on such sources for passwords in order to check against the hashes they steal. Checking them against these lists will therefore make it even harder for hackers to figure out your plaintext passwords.
Password storage best practices are a critical part of the SDLC
Passwords are a vital part of your application. Proper password storage matters in the long run. Depending on how critical the user data is, storing a breached password can bring your entire company down.
Poor password practices can lead to many security problems: They can enable both external and internal attackers while also making you vulnerable to reused passwords from other applications. If user compliance goes down, this can also lead to frustration among users and reduce compliance, thus increasing security risks. Worse, it may also discourage people from using your service.
When building critical software, security best practices must be applied at every layer of the development process. Password security is just a small part of the secure SDLC. Prevent attackers from getting to your passwords in the first place. The Snyk Code static application security scanner checks your code for well-known vulnerabilities and tells you how to fix them.
Benefits of security analytics
Learn more about security analytics, a proactive security approach that detects advanced security threats with artificial intelligence and machine learning.Keep reading