Is client-side hashing secure?

A lot of web developers seem to believe that client-side hashing is a valid substitute for sending passwords over a secure SSL-encrypted link (in this case, HTTPS). Some even believe that it is more secure, simply because the user’s password isn’t sent over the network as “plaintext”. Unfortunately, a lot of this is based on a bad understanding of why we use password hashes in the first place.

Typically, client-side hashing is used in order to try and prevent man-in-the-middle attacks. However, to an attacker, it doesn’t really matter if they can see the user’s plaintext password or a SHA1 hash. The attacker only cares about what is being sent to the server. In other words, what is the server expecting?

If I can sniff out the fact that a client browser is sending “aab0969638e3cd6d63b4b0bba36f8d041dbf1d78” as a password parameter, what’s to stop me from re-sending the exact same hash? Will your server know the difference?

Secondly, if client-side hashing is used as a substitute for server-side hashing, then you might as well be storing plaintext passwords. The attacker doesn’t care if he or she can see the user’s password or not. The only thing that they care about is being able to authenticate with the server. The worst thing is about all of this is: You’ve completely forgone the benefits of using a slow hashing algorithm such as bcrypt, as an attacker could potentially throw a bunch of pre-fabricated hashes at your server.

Finally, I think there is something to be said about the dangers of conflating password security with transport security. Protection against eavesdropping is the job of SSL, not hashing.