Preventing Compromised Password Reuse on HackerOne.com
This week, we rolled out an improvement to account security on the HackerOne website. We now block the use of any password known to have been compromised in major data breaches. This applies to all new accounts created by our customers and ethical hackers, as well as password resets performed by all existing accounts.
We do this through integration with Have I Been Pwned, a free-to-use service that allows anyone to check if their account data had been stolen or leaked in major known data breaches. We use their Pwned Passwords API to check against their database of nearly 850 million unique compromised passwords. The database is continually updated, providing ongoing protection from new compromises. Since its launch in 2017, the total number of compromised passwords has nearly tripled.
When creating a new account or changing an existing password, the HackerOne website will perform a series of checks to make sure our users are picking a secure password.
All passwords must meet our own requirements, which include a 12-character minimum and an entropy check to make sure the password is not easily guessable. These requirements block the use of generic and weak passwords that are widely reused across the internet.
Passwords that meet our requirements are then checked for compromise against Pwned Password’s database. We look for a match to any known compromised password, not the unique combination of your email address and password. While this may seem overly cautious, it provides the best protection against the ways malicious attackers use compromised passwords.
As computing power becomes cheaper and more accessible, industry standards for password security must increase to keep pace. Password security is increased by using longer passwords with more unique characters. As you lengthen a password the total number of possible passwords - known as the password space - increases exponentially. There are 800 quadrillion possible 10-character alphanumeric passwords. The password space for a 12-character password is four-thousand times larger than that.
If an attacker does not know how long your password is, they are stuck checking all possible combinations for multiple character lengths - that is a huge password space to deal with. The least efficient way to guess a password is through brute forcing (using software to try every combination). Brute forcing becomes less efficient as the total password space increases. However, when passwords are stored with cryptographically secure hashes, there may not be many shortcuts.
So what can a malicious attacker do to improve their odds? If an attacker knows a password has been used for an account, it has likely been reused used somewhere else. Lists of commonly used and previously compromised passwords, known as dictionaries, are readily shared on the dark web and forums. This is where most of the passwords in Pwned Password’s database come from. While the 850 million passwords in their database may sound like a lot, that is only a tiny fraction of a single percent of the total password space, and much faster than randomly guessing. This is why avoiding a known compromised password - even if you have not previously used it - is so important.
While we are talking about password hygiene, remember best practices are to use a randomly generated password created by your password manager, and use multi-factor authentication on all websites that support it.
Checking for Compromise
Typing your password into a website to see if it's compromised may sound like an easy way to get it compromised, but multiple layers of security allow us to check if your password is known to be compromised without ever exposing your complete password to any third parties.
First, we create a SHA-1 hash of your new password. A hash is a type of cryptographic algorithm that takes any input (in this case, your password) and transforms it into a hash value. As a simplified example, the word “hacker” becomes the hash value “3aa781b7”. A secure hashing algorithm produces a unique hash for every input, and it is infeasible to reverse the hash to discover the original input.
We then query Pwned Password’s API to look for a match. Only the first five characters of the hash are sent, and a complete list of every hash starting with those characters is returned. On average, nearly 500 partial matches are found.
This provides additional security by keeping the entire hash value (which is already obfuscated and secure) secret - it is never transmitted outside of HackerOne. If our website finds a complete match an error message is shown, asking you to pick a different password.
In addition to all these measures, every connection to Pwned Password’s API is protected by an HTTPS connection, the same technology used to protect your connection to nearly all websites including this blog post.