The news is full of examples of leaked databases (this is just the most recent results).
The How:
The vast majority of cases involve unsecured databases/backups (across pretty much all technologies: S3, mongodb, cassandra, mysql, etc....). These are usually due to configuration errors, bad defaults, or carelessness.
What data is leaked:
These generally provide at least read-only access to some or all of the data contained in the database, including usernames and hashed-and-salted passwords.
These dumps include a lot of private user records. Plaintext passwords (or using a simple hash such as md5
) are even more problematic because that data can be used in credential stuffing attacks (by trying the same username/password combinations on different websites), potentially accessing even more data.
What to do with a password hash:
If an attacker has access to a hashed and salted password, they cannot just provide this to the server to authenticate. At login time, the server computes hash(salt + plaintext_password)
and compares it with the value stored in the database. If the attacker attempts to use the hash, the server will just compute hash(salt + incoming_hash)
, resulting in a wrong value.
One scenario that could spell a lot of trouble is client-side-only password hashing. If the client computes and sends hash(salt + plaintext_password)
into the login endpoint, then the stored hash can be used to login. This alone shows how dangerous that is to do. There are some algorithms that offload some of the work to the client (such as SCRAM) but they involve a more thorough client-server exchange to prevent exactly this scenario.
Password storage security is worried about attackers deriving the real password from the stored value. It is not concerned with other vectors of attack against the server.