Online bruteforce attacks
Indeed, sites that don't implement some form of protection against online bruteforce attacks are leaking their users' passwords. Many sites don't have any form of protection in place, and many others do.
Simple blocking has issues:
- If we block the user's IP after x failed tries, a 10'000 strong botnet gets to try x* 10'000 passwords. At 100'000 tries a lot of the weaker passwords are already cracked.
- If we block the user's account after x failed tries, any attacker can block any user's account.
This implies that the defense needs to be more sophisticated, or we can simply ignore defense and try to blame the user when it eventually blows up, which is less than ethical. More sophisticated schemes use some combination of detection of suspicious activities, and conditionally stronger login requirements.
To detect suspicious activities we track positive signs based on successful past successful logins, such as the ISPs of the user and some identifier of the devices that the user logged in with before. We can also use negative signs such as IPs from "tainted" ISPs or countries, or a rapid increase in login attempts.
In terms of stronger login requirements we can use short timeouts, captchas, multi-factor authentication, and even blacklists.
Offline bruteforce attacks
All the above measures are useless once our disgruntled system administrator sells a copy of our password database on the black market, because then the attacker can just hash the password himself and see if it matches the database. Cracking the the hashes can be cheap and easy or still easy but very very expensive, depending on how we hashed the passwords
See: How to securely hash passwords?
Salt: To make it harder on the attacker to crack the whole database, we use a salt, which makes each hash slightly unique. Every user has a different salt, which is stored next to the hash. This means the attacker can't just calculate the hash of one password and compare it against every user's hash, but instead the attacker has to calculate a new hash for every password he tries against every user. Using a salt does not increase the cost to get the password of a single user.
Expensive Hash: No attacker can bruteforce 100 billion passwords a second, unless the hashing scheme was set up by a moron (which is plausible). Some attackers can calculate 100 billion basic hashes like sha256 per second, but the solution is simply to not use a basic hash to hash the password. A trivial solution is that our hash isn't actually
hash =sha256(password, salt), instead it's
hash =sha256(sha256(sha256(.......(password, salt)...)password, salt)password, salt), where we use around 100'000 iterations of sha256, making any attack 100'000 times more expensive. In reality this defense is too simple to break with specialized hardware, so in practice we use special Key Derivation Functions tike
scrypt to mix multiple basic hashes in ways that are expensive for any attacker to calculate, regardless of hardware.