Recommendations to End-Users
In the most ideal circumstances, we (as security consultants, developers and just general security-minded individuals) should be encouraging users to use password managers to, well, manage their passwords.
Most password managers can create bespoke, complex, and secure passwords for each application reducing the impact of any future breaches that result in password leaks. There are plenty of password managers out there, we’ve selected a few for you to consider (but please do your own research to see if it’s suitable for you):
- KeePass is an offline open-sourced password manager that works for Windows, Linux and MacOS. However, there isn’t an accompanying application for mobile phones.
- BitWarden is an online open-sourced password manager that works for most operating systems including mobile OS’s and provides a web-portal. There is a self-hosted version but there is an online version run by BitWarden Inc.
- LastPass is an online password manager that similarly works for most operating systems and provides a web-portal.
Most password managers also allow you to carry out security checks against known breaches so that you know if your passwords have been compromised.
Recommendations to Application Developers
As for developers, our recommendations includes additions to the password policy recommendations provided in Figure 1. As well as requiring, a server-side check against lists of commonly used passwords such as the GitHub 500 Worst Passwords or SecList’s top 10,000 Worst Passwords.
> Classical Password Complexity Policy
What’s important is to make sure that there are both in-browser and server-side controls for password strength. Using an in-browser control can reduce the number of submissions to the server, but it cannot be relied on since all client-side controls can be bypassed.
Ultimate control for password strength must lie with the server-side checks. These controls should assess the user’s password against the following guidelines and enforce at least three of the four criteria given a minimum password length greater than 12:
- 1 or more lowercase letters (A-Z)
- 1 or more uppercase letters (a-z)
- 1 or more number (0-9)
- 1 or more special character
This recommendation (as discussed above), is the classical approach to password complexity policies. Whilst it’s generally sufficient for providing a baseline security model, users often try weasel their way around password requirements. For example, a user willing to use the root word “password” would augment it to something like “Password123!” (without the quotes). This is objectively still weak despite matching strict complexity rules.
> Password Blacklist
To guard against this, passwords should be checked against common password lists such as such as the GitHub: 500 Worst Passwords or SecList’s top 10,000 Worst Passwords on the server-side. These lists of common passwords have been generated by cataloguing passwords generated by humans from various database breaches.
If your application allows users to select their own username (instead of using email addresses), then you should make sure that the list of blocked passwords includes variations of the usernames. For example, this would prevent the user “Avenger” selecting the password “Avenger1234!”. The reason for this specific check is because users often select passwords related to their username.
Alternatively, consider using a third-party such as HaveIBeenPwned have provided APIs that allow developers to check if a user’s password has been compromised in a previous data breach. By utilising these APIs, you can stop users from using weak, compromised passwords.
> Multi-Factor Authentication
For accounts that are considered especially sensitive (such as the administrator), consider the following:
- Implementing multi-factor authentication
- Increasing the password’s minimum length greater than 16
> Additional Security Mechanisms
The following recommendations stray a bit from “Password Complexity Policies” but can be used to help limit automated password-guessing attacks by bots.
We want to limit the rate at which users can send completed login forms to bots. This can be done with one of the following methods:
- Implementing reCAPTCHA to analyse the behaviour of user’s to determine if they are a bot or not. This helps reduce automated actions from these bots.
- Rate-limiting important form actions such as login forms to reduce the effectiveness of automated password-guessing attacks.
- Implement monitoring on the login form to alert whenever numerous failed login attempts are made against accounts. These may simply be a message on the user’s dashboard to inform them of the last failed and successful login.
Although individuals methods may not provide the 100% protection that you want (as there are ways around each one), by combining multiple methods we can reduce the effectiveness of these bots.
One additional method to consider is to implement an account timeout mechanism. This works on the idea that following some set number of failed logins (for example, 5 failed logins), the account is temporarily locked out for 1 minute. Again, the idea of this mechanism is to make it more difficult for automated password-guessing bots. However, you have to consider the fact that this mechanism can be abused to cause denial-of-service to legitimate users by bots sending login attempts for all your users on your application.
> The Login Form Itself
In addition to the requirements, it is important to ensure that the password field does not:
Restrict the maximum length of password: Doing so hinders users who would select more robust passwords. It is common for security conscious users who encounter a maximum length check to voice concerns publicly resulting in minor reputational damage. It may be an indicator that the password storage in the database is insecure since appropriately hashed passwords would have a fixed storage length regardless of the source password.
Restrict the use of copy and pasting passwords from password-managers: Password managers are also increasingly used by security conscious users and failing to enable their use is an inconvenience which is also often voiced publicly. Most password managers randomly generate each password before pasting it in when required. By removing the element of human choice, the complexity is more robust against brute-force.
> One Final Thing
All of these recommendations are based on current research and the things that we’ve all seen in the wild. They’re written in the hopes that more application’s out there start using more secure password complexity policies.
However, you can absolutely go nuts on the level of security that you implement on an application. For example:
- You could enforce IP restriction to only allow logins from trusted IPs (useful for internal applications).
- Restrict access to applications for users with client-certificates only.
- Individual login URLs for users to make it more difficult for bots to carry out automated password-guessing efficiently.
But for the majority of Internet-facing applications, these recommendations are excessive and just cause user’s more headaches than they’re worth. Consider your user-base and apply the recommendations as seems appropriate.