28

So the traffic is encrypted to a website so the password is safe during transmission and also if the website is hacked then the database only contains hashes.

But couldn't the hacker create a server side script to store the usernames and passwords used to login to the website in a file since they are decrypted and are not already hashed? This wouldn't get every user however it would allow them to view users passwords who try to log onto the site while it is compromised.

Wouldn't it be better to hash passwords at the client side?

  • 1
    No one will task about SRP? It's important as it protects the password from the server without using password-equivalents and just have the problem that, without an native implementation by browsers (which seems no one wants), it can be maliciously replaced, like happens with hashing. (BTW, do you still support non-javascript users beside search bots? those bots don't login!) – Gustavo Rodrigues Aug 13 '15 at 20:18
  • See Digest Access Authentication – el.pescado Aug 14 '15 at 8:38
61

The weakness you allude to is real. An important point is that once the server is compromised, the attacker has little incentive to grab passwords that grant access to that server -- he is already in the place. However, human users have the habit of reusing passwords, and that is a big problem, because a reused password means that compromises on one server tend to "propagate", exactly in the way you explain: the attacker grabs password P for user U, and guesses (alas correctly, most of the time) that the same user U will have used the same password on some other servers.

Hashing client-side is a nice idea, but there are details:

  • Whatever the client sends to the server, be it the password itself or the hashed password, grants access. It is password-equivalent. If the server stores these hashes "as is" in its database, then it is in the same situation as a server storing plaintext passwords, and that's bad. Thus, the server MUST also do some hashing.

  • Client-side hashing occurs only if there is code on the client side that does the hashing. In a Web context, this means JavaScript. Unfortunately, JavaScript is poor at cryptographic implementations; in particular, it is quite slow, so the client-side hashing will not be able to use the many iterations that are usually needed for good password hashing (see this for details). Also, this would not work for clients without JavaScript.

  • Still in a Web context, the client-side hashing, if it occurs, is done by JavaScript code sent by the server. If the server has gone under hostile control, then it may send malicious JavaScript that pretends to do the hashing, but does not. The user will be none the wiser. Thus, the root problem is not solved.

Client-side hashing is usually envisioned under the name of "server relief", not to increase security against evil servers, but to allow the server to handle many concurrent users without spending all its CPU on a lot of hashing. JavaScript being what it is, this is not commonly done nowadays.

  • 6
    You know, I just realized client side hashing actually makes some sense, because if the attacker wishes to retrieve the plain text passwords he will need to disclose the fact that he has compromised the server (change the source files) if properly monitored. It forces the attacker to do an active attack. Of course it won't help at all in most of the cases, but at least it does have theoretical benefits (I thought it didn't have any). – David Mulder Aug 12 '15 at 23:42
  • 3
    Client side hashing also helps with the problem of a user using the same password on multiple sites. From the standpoint of password equivalence, it may be true for this site, but that hash cannot be used for multiple sites (for instance if he domain name is involved in the hashing). – Frank Bryce Aug 13 '15 at 12:11
  • 1
    @Jason Not saying that current monitoring already is sufficient, but at least it can be monitored. Just request a fair number of pages from your site and anytime it changes issue an alert to the head of development. If this lines up with a new version that is being pushed to production: Good. If not: Go and check. – David Mulder Aug 13 '15 at 12:27
  • 1
    @Jason I'm not saying it's bullet proof, but then again nothing really is. My only point was that hashing on the client side would be another layer to make it harder for a malicious hacker to get passwords which may be used on other sites. And like David said, this would require an active attack rather than passive observation. – Frank Bryce Aug 13 '15 at 12:55
  • 1
    @Jason SHA256 is woefully insecure these days? That's just rubbish. Yes, if you have a password with very low entropy (a literal dictionary word), the hash has been properly salted, you know the salt and have a GPU to run the hashing then in somewhat reasonable time (a second or so) you will be able to find the password. But given a leaked database with SHA256 passwords where some of them have high entropy if you wish to crack all of (cont.) – David Mulder Aug 13 '15 at 14:22
14

So there's two separate parts to this.

First, the server getting compromised, and second, sending hashes to the server instead of passwords.

For the first part with the server getting compromised, yes, the attacker could pretty much do whatever they want. If they own the server, they can indeed get the usernames and passwords from the users being passed to the server. This is why servers need to be hardened against attacks and regularly updated so that they offer as little of attack surface as possible.

For the second part, if you have the client pre-compute the hash, then that hash has literally become the password. If an attacker were to have stolen the database of hashes(but hasn't compromised the web server), he doesn't need to find the passwords that turn into those hashes; he can just send the hash to the web server, and it would authenticate since the server would already be expecting a hash as input to compare against its database.

  • 4
    Yes, but on the other hand, the point of hashing passwords isn't to protect users' access to that site. (If you pwn the database, you can copy all of the users' data anyway; you don't need their login credentials.) The point of hashing passwords is to protect all those poor idiot users who use the same password everywhere, so that the hackers don't have access to the entire rest of their online identity. – Mason Wheeler Aug 12 '15 at 21:10
  • 2
    @MasonWheeler That assumes that the attacker's only goal is to access data which is stored in the database. What if his goal is to access a CMS and deface webpages, or delete user accounts by logging in as an admin? – Eric Aug 12 '15 at 21:32
  • @Eric if I pwn the database, couldn't I (1) make a copy of the user's hashed password, (2) pick a new password, (3) computer the hash of the new password, (3) replace the user's hashed password with my hashed password, (4) authenticate as the user, (5) do whatever I want, (6) replace my hashed password with the user's hashed password so the user won't know I changed his password. – emory Aug 13 '15 at 0:11
  • 1
    @emory If you have write access to the database, yes. – Eric Aug 13 '15 at 0:18
  • 2
    Bear in mind that a common scenario for illicit access is attacker access to backup media.  (I've heard stories of backups being thrown out in the trash/recycling.)  If the site doesn't have an aggressive frequent-password-changing policy, an old backup of the password (hash) store may still be highly current.  This and other scenarios may lead to a one-time read-only access to the password data (e.g., a zero-day code injection attack against the login program may yield that, and only that, without providing broader access to the site). – Scott Aug 13 '15 at 5:07
1

You likely wouldn't be able to prevent simple server-side modification of the code sent to clients to execute if your server is totally owned.

However if this is part of a pre-installed or pre-distributed software package with distinct client and server components (this could include web applications with downloaded components that stay resident on the client OS), client side hashing could be useful in the sense that, while the attacker can likely still use those hashes for authentication to YOUR database (or just reset passwords as mentioned in one of the comments), they no longer have easy access to the plaintext password that would be sent to your server (over SSL) for salted hashing and database storage.

So, if you have a client using the same password in multiple places, so long as the hash isn't trivially reversible, your particular server compromise has no longer disclosed credentials the attacker can use elsewhere. This would be enhanced with random client-side salting (so that you're not ending up with the same hash that the same algorithm would always generate for that plaintext).

1

I find a lot of people (especially in the PHP realm) misunderstand what hashing does. Here's the methodology

  1. User creates account and sends a username/password combo to you (securely over HTTPS I hope)
  2. Password is hashed on the server (with a random salt) and stored with the username
  3. User comes back later and enters their plain text password
  4. Server finds the stored hash for the username. With $2y hashes (BCRYPT) the cost and salt are stored in the same string. So using the same cost and salt, the server generates a hash using the user provided password (remember, hashes are one-way by design)
  5. With everything being the same, if the generated hash matches the stored hash, we can authenticate the user

Assuming that someone hacks your server your users are better protected because the salt is random for each hash. As such, you would have to brute force each password separately (the core theory behind any type of security is to raise the cost of doing something to the point where someone will not attempt it). SHA1 and MD5, the previously popular hashing systems, were almost always generated without any salt, making them susceptible to not only any weaknesses in the hash itself, but rainbow table attacks (without salt each SHA1 and MD5 is the same for a given string).

There's really no way to do this client side because

  • The client is in the hands of the enemy. So you would have to send the client everything they need to generate the hash (most notably the salt) and then have them pass back the hash.
  • As mentioned in another answer, at that point their hash becomes the password because that's what they send to you. In other words, even though I might not know what the password is, you're still doing simple string comparison instead of generating a secure hash so I can break in
-2

No, Inspect Element or something similar exists on most browsers, allowing anyone to bypass client-side code. If a hacker got access to the database, they could remove the hashing code using Inspect Element and enter the hashes as passwords, or edit the page to not hash it anyway. How about instead, a script that stops the server if it senses a page has been modified by a hacker?

  • 1
    "inspect element" is not what you were going for – schroeder Aug 13 '15 at 22:28
  • Having access to the code which performs the hashing isn't enough - you still need to know what was input into the algorithm to generate the hash. Also, how would you implement a system to detect a page which was modified by a hacker from a legitimate modificaiton or deal with dynamic pages? – Tim X Aug 13 '15 at 22:49
  • This makes no sense. If a hacker got access to the server, they still cannot use "inspect element" on any clients than his own. – Bergi Aug 14 '15 at 9:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.