Secure authentication is essential to keeping your users safe. This means dealing with passwords safely.
If your user accounts get hacked easily, you quickly won’t have any users. Ensuring strong authentication is a mix of pushing your users into good habits, and following them yourself. Attackers are constantly trying to find ways to bypass authentication, so you need to make sure you do not permit any vulnerabilities.
Use Third-Party Authentication if Possible
The most secure code is the code that isn’t there! Consider using third-party authentication instead of building your own. Some commonly used implementations:
Integrating third-party authentication into your site will make sign-up seamless for your users, and completely remove a possible attack vector on your site. Modern authentication systems have detailed developer documentation, and SDKs for a variety of programming languages.
Ensure Password Complexity
Make sure passwords have a minimum length, and if your site deals with sensitive data, consider enforcing password complexity rules. This typically means requiring mixed-case letters, and requiring one or more numeric or symbol characters. You might also have a blocklist of “obvious” passwords, or ban passwords with too many repeating symbols.
Allow Password Resets via Email
The most secure way of implementing password resets is to allow users to send themselves reset links in email. Make sure reset links time out.
Confirm Old Password On Reset
If a user is already logged in and is resetting their password, have them confirm their previous password. This will protect your users if they leave themselves logged in to public computers.
A common avenue of attack uses scripts that repeatedly try to login with known usernames and common passwords. This is computationally cheap, and many utilities exist to automate this attack. Large “password dumps” – leaks of passwords from historical hacks – give an attacker a good idea of what phrases people commonly use as passwords.
The first defense against this type of attack is to prevent user enumeration. If you don’t give any feedback when a brute-force attack guesses a usernames correctly, you substantially increase the number of guesses needed to hack an account.
The second defense is to “punish” multiple failed login attempts with the same username. Very secure systems will lock the account until an administrator intervenes, but this is very manually intensive. Locking the account temporarily (even for just a few second or minutes) is often enough to make brute-force attacks ineffective. Otherwise, asking the user to perform an action to prove they are not a script – like solving a CAPTCHA – will do the trick.
Store Passwords With A Strong Hash, Salted
Passwords should always be stored as salted hashes.
A hashing algorithm is a one-way transformation that obscures the original input, but can be used to test if the input is entered correctly again. By saving passwords in hashed form, even an attacker (or a malicious employee!) who gets access to your database cannot make use of the account details.
Hashing is a very positive step, but still vulnerable to an attacker able to generate a rainbow table – a list of pre-calculated hashes of common passwords. This type of lookup attack can be defeated by adding salt to the hash – an element of randomness that will make the same input create a different hash, but still usable to check the correctness of the input when entered again.
Timeout Sessions After Inactivity, and Provide a Logout Function
You can put all the security you want on the front door, but if you don’t allow users to close it when they are done, it’s all for nought. Provide a logout button, so users can leave their session when they are done interacting with your site. Moreover, if your site handles sensitive data, timeout the sessions after a period of inactivity. (Users frequently neglect to logout, after all.)
Use HTTPS for Secure Communication
Make sure you use encrypted communication when asking a user for their login details, or else their password can be stolen by a man-in-the-middle attack. Similarly, make sure all communication between your server and their browser after login is done over HTTPS, so their session cannot be hijacked.