104

There are very few websites that hash the users password before submitting it to the server. Javascript doesn't even have support for SHA or other algorithms.

But I can think of quite a few advantages, like protection against cross-site leaks or malicious admins, which SSL does not provide.

So why is this practise so uncommon among websites?

Maestro
  • 1,153
  • 2
  • 8
  • 8
  • 13
    What advantages do you think there are to client side hashing of passwords? – Tim Lamballais Mar 18 '14 at 10:34
  • 10
    @TimLamballais A typical client can spend far more time on hashing than a server. So if you have a high performance implementation in the client (which rules out javascript in current browsers) you can use more expensive and thus stronger password hashes. It also means that the server never sees the password itself. Client side hashing is also a prerequisite for augmented PAKE protocols like SRP where impersonating the server doesn't give you access to the password. – CodesInChaos Mar 18 '14 at 10:58
  • 6
    Javascript isn't really that slow anymore. Modern javascript engines have become so fast that they are on-par with compiled languages and recent additions like typed arrays provide the proper tools for the number-crunching required for cryptography. – Philipp Mar 18 '14 at 11:57
  • 10
    @TimLamballais One advantage would be that the server never sees my real password, and cannot possibly leak it (yes, they can still leak the hash, but it should be salted by the domainname, so useless for login to other sites). But for the largest advantage see my comment to Phillip's answer. – Maestro Mar 18 '14 at 13:43
  • 3
    A lot of people question whether any extra security is gained with this practice. One thing it does do is reduce risk. If you always hash or encrypt (I've seen steam/valve encrypt with a public key and I bet they are not decrypting) there is no chance of you ever having an embarrassing plaintext breech. No...it isn't any more secure but it isn't pointless –  Mar 18 '14 at 14:34
  • 1
    WPA2-PSK uses client-side hashing of password for authentication. – defalt Nov 30 '16 at 11:33

12 Answers12

71

Inventor of JavaScript password hashing here

Way back in 1998 I was building a Wiki, the first web site I'd built with a login system. There was no way I could afford hosting with SSL, but I was concerned about plaintext passwords going over the Internet. I'd read about CHAP (challenge hash authentication protocol) and realised I could implement it in JavaScript. I ended up publishing JavaScript MD5 as a standalone project and it has become the most popular open source I've developed. The wiki never got beyond alpha.

Compared to SSL it has a number of weaknesses:

  • Only protects against passive eavesdropping. An active MITM can tamper with the JavaScript and disable hashing.
  • Server-side hashes become password equivalents. At least in the common implementation; there are variations that avoid this.
  • Captured hashes can be brute forced. It is theoretically possible to avoid this using JavaScript RSA.

I've always stated these limitations up front. I used to periodically get flamed for them. But I maintain the original principle to this day: If you've not got SSL for whatever reason, this is better than plaintext passwords. In the early 2000s a number of large providers (most notably Yahoo!) used this for logins. They believed that SSL even just for logins would have too much overhead. I think they switched to SSL just for logins in 2006, and around 2011 when Firesheep was released, most providers switched to full SSL.

So the short answer is: Client-side hashing is rare because people use SSL instead.

There are still some potential benefits of client-side hashing:

  • Some software doesn't know if it will be deployed with SSL or not, so it makes some sense to include hashing. vBulletin was a common example of this.
  • Server relief - with computationally expensive hashes, it makes sense for the client to do some of the work. See this question.
  • Malicious admins or compromised server - client-side hashing can prevent them from seeing plaintext passwords. This is usually dismissed because they could modify the JavaScript and disable hashing. But in fairness, that action increases their chances of being detected, so there is some merit to this.

Ultimately though these benefits are minor, and add a lot of complexity - there's a real risk that you'll introduce a more serious vulnerability in your attempt to improve security. And for people who want more security than password, multi-factor authentication is a better solution.

So the second short answer is: because multi-factor authentication provides more security than client-side password hashing.

Luc
  • 31,973
  • 8
  • 71
  • 135
paj28
  • 32,736
  • 8
  • 92
  • 130
  • 5
    What if, _the server has been compromised_ by a cracker and he'd like to gather plain passwords from clients to use them at other places? No safeguard but client-side hashing. Why must we force clients to trust the server? – Константин Ван Feb 04 '19 at 07:16
  • 1
    @КонстантинВан - please refer to the "compromised server" part of the answer – paj28 Feb 04 '19 at 10:04
  • 3
    Another drawback of client side hashing is that you cannot enforce password policy on the server. Basically you cannot validate that the user selected password is strong enough – Michael Apr 16 '19 at 06:24
  • 7
    @Michael That's a good thing in my opinion, since password policies on most servers are ridiculous. Many password characters are forbidden for no reason. – Tomáš Zato - Reinstate Monica Jun 18 '19 at 10:04
  • Clientside-salted hashing completely ELIMINATES the need for any for password policies. THIS IS WHY IT SHOULD BE DONE. – 8vtwo Aug 09 '21 at 05:41
  • @Константин Ван If the server is compromised then no password scheme is effective. What is your point? At least in this scenario, a database bruteforce becomes impossible. – 8vtwo Aug 09 '21 at 05:43
  • @Tomáš Zato THIS IS THE ANSWER I CAME HERE TO SEE. LOCALLY HASH PASSWORDS, KILL STUPID PASSWORD POLICIES. – 8vtwo Aug 09 '21 at 05:46
  • @8vtwo The point is: _if a user has a client that hashes_ (with a salt) his plaintext password prior to sending it to the server, the compromised server cannot keep it and use it to sign in to other services; because plaintext passwords are not sent. Well, yes; for web services, it could be pointless as the server can alter and redistribute the code running on the client side. The pros of the client-side hashing is only for services where an update to client code is in control of the user; like client executables, not web services. – Константин Ван Aug 09 '21 at 14:08
  • @Константин Ван This makes no sense. 1. If site is compromised, its use of the webservice is compromised as well so there is no difference or benefit 2. You are just moving the hack down the line, now the "webservice" has to be hacked for there to be damage? You aren't making ANY SENSE. – 8vtwo Aug 09 '21 at 14:46
  • @8vtwo 1. By "compromised," I mean the attacker seizing the server and _having it pretend to be normally functional._ 2. By "web service," I mean the server and client; that are on the web, where the server can alter the code on the client side any time it wants (where the client loads its code from the server.). 3. I hope that makes sense to you now. – Константин Ван Aug 09 '21 at 18:04
  • @@Константин Ван You didn't clarify anything I didn't already know. FACT: There are NO KNOWN DISADVANTAGES to client-side hashing ALONG WITH serverside hashing. There are ONLY ADVANTAGES. IF YOU DISAGREE PLEASE STATE REASONING. – 8vtwo Aug 10 '21 at 03:36
  • Now I see. Listen, @8vtwo, I wasn’t talking about why you shouldn’t do client-side password hashing. Chill and tone down a bit. I’ve been here for it, not against it. – Константин Ван Aug 10 '21 at 04:26
55

To understand this problem, first you have to understand why we hash passwords. It is completely possible to store a password in plain text on a server and simply compare the password transmitted to the password received. As long as the password is protected in transit, this is a secure means of authentication (shared secret).

The reason that passwords are hashed is because the problem isn't the authentication, but the storage. If the server is ever compromised, the attacker would immediately have access to all user accounts as they would now know the secret used for authentication of the users.

Hashing acts as a barrier to this. Since the server doesn't know the actual input required to authenticate, even a compromise to the DB does not grant an attacker access to the user accounts. They would still need to figure out the input to give to reach the hash values the application checks against. Sure they could alter all the values to something they know, but this would rapidly throw up suspicion and the system would be shut down and secured.

So, the problem with client side hashing is that it effectively makes the result of the hash the password rather than the password. There is nothing to stop an attacker from bypassing the official client and simply sending the finished hash to the server directly. It provides no additional (or loss) of security during the authentication, but under the situation that hashing is designed to protect against, it offers nothing since the hash stored in the DB is actually the shared secret transmitted to the server.

That said, there are two notable thing client side hashing does give you. While it doesn't help protect your system at all, it may help protect your user. If you are insecurely transmitting the password or the transmission gets compromised without the client code getting compromised, you will still protect the user's password (which they may reuse on other sites) from being leaked.

The other is that you can provide additional iterations of a hash to make an offline attack against the DB more difficult without having to use server cycles (while also extending the length of the "intermediate password that the client submits"), but you still need sufficient server cycles to protect the lengthened password against a rogue client. Again, the primary protection this offers is preventing the original password from being discovered but does nothing for helping protect the authentication mechanism of your site.

Put another way, while it does provide some minor protections, from the point of view of the server, the client side hash should be treated as if it was the user's direct password. It provides no more or no less security on the server than if the user had directly given their password and should be protected as such.

If you want to be able to provide that extra level of security, I would recommend two hashes. Hash once client side to build a new, unique password, then hash that password on the server to make a value you store in the DB. This way you get the best of both worlds.

For the most part, SSL is trusted sufficiently to protect the exchange that the initial hash prior to transmission is seen as unnecessary though and a compromised server could always alter the code sent to the client such that the initial hash isn't performed. It simply isn't an effective alternative to SSL and doesn't offer enough additional advantage to be worth the costs and complexity.

AJ Henderson
  • 41,816
  • 5
  • 63
  • 110
  • I need to encrypt some data client-side, and by sending only the hash to the server, I can proof that the server cannot decrypt the local data, since it doesn't know the plain-text password. Also, when salting the hash with the domainname, there is a garantuee that the server can never leak my password, just a salted (useless) hash. – Maestro Mar 18 '14 at 13:46
  • @Muis my point is that the salted hash isn't useless. It can compromise the integrity of your authentication system as it is the new password for authentication (even if not for encryption). The attacker could still get the hash from the DB on the server and convince the server that they are the user and access the encrypted copy of the files (which granted, they may have access to already anyway at that point). Additionally, a salt should be globally unique, not a domain name. – AJ Henderson Mar 18 '14 at 13:49
  • 5
    @Muis - my point is simply that you should treat the hash generated client side as if it was the user's own password when dealing with it server side. It isn't bad to use a client side hash to protect the user's password from being exposed to the server, but it practically acts like the user's direct password as far as the server is concerned. – AJ Henderson Mar 18 '14 at 13:52
  • 1
    My main worry is that the leaked password can be used to login to OTHER sites, where the customer used the same username/password combination. This will be prevented by adding the domainname to the hash (since I cannot store an unique value persistently in javascript). – Maestro Mar 18 '14 at 14:10
  • @muis the salt need not be protected. Store it on the server and send it to the client before hashing. If the server can't be trusted for this, still use the domain name and user name appended to the server supplied data perhaps. – AJ Henderson Mar 18 '14 at 14:12
  • 6
    Why not simply do both then? Hash on the client side to avoid leaking the actual clear-text password and hash again on the server side to avoid the hash-becoming-the-password problem. – Xaser Aug 27 '16 at 08:29
  • @xaser - you could, but it wouldn't add much. That's basically what muls and I were talking about in comments. It only comes in to effect if you have a man in the middle that can only observe (otherwise they could strip the client side hashing) and only makes a difference if the salt is globally unique (can't be rainbow tabled) and the password itself is secure enough to resist being brute forced with a hash cracker. It does not protect the site itself as the client side hash IS the user's password for that site and only would protect shared passwords (which are bad anyway). – AJ Henderson Aug 27 '16 at 13:22
  • Does hashing on client side and on server side not provide just as effective security as using SSL/TLS to transmit passwords in plaintext. If not even more secure if these protocols were to be broken? Length is not considered here, complex passwords could be a requirement if needed @AJHenderson – uhfocuz Aug 28 '16 at 02:55
  • 3
    @uhfocuz No. Not at all, for a great many reasons. The primary issue is that for login purposes, the client side hash would be the user's password, not whatever the user types, as the server can't verify what the client side did. Further, without protection on the channel providing the content of the page, a man in the middle could simply strip the client side hash entirely and capture the user's password. Finally, even without these issues, unless the password represents the same degree of entropy as the key used in SSL, it would be easier to brute force a hash collision. – AJ Henderson Aug 28 '16 at 05:19
  • @AJHenderson what if the "hash being the users password" is providing a more secure medium, and two completely separate hashing algorithms were used on client and server side. And just to appease you, SSL is also being used here. Would this be an okay dynamic for secure client side hashing, while also keeping the nature of the hash securely stored on server side. – uhfocuz Aug 28 '16 at 17:07
  • 1
    @uhfocuz that's my point. It doesn't provide a more secure medium. Two different hashing algorithms doesn't really matter. I never said you couldn't do a client side hash, just that the nature of a client side hash really doesn't offer you much of anything in terms of security. It only protects a user that is using the same strong password in more than one place from having the password sent to the server. That's a very limited advantage for quite a lot of work and potential increased xss surface area. – AJ Henderson Aug 28 '16 at 17:45
  • @AJHenderson I still am strongly opposed to your claim that this would provide very limited advantage, it would double bruteforcing times, never could the real password be easily divulged in the scenario our HTTPS protocols are already broken, and XSS, no, tampering, yes but this data originates to the registration, would be just as effective as really using tamper data – uhfocuz Aug 28 '16 at 17:49
  • @uhfocus it would not have any impact on brute force time that extra runs server side wouldn't have and provides no advantage at all to the site implementing it as the client side hash is irrelevant to the authentication. If ssl breaks the system offers no advantage at all as it does not provide any integrity check or server authentication. The only advantage it offers is the one I described. If it provided what you describe it would be great, but it doesn't. – AJ Henderson Aug 28 '16 at 18:08
  • We can keep discussing this in chat [here](http://chat.stackexchange.com/transcript/message/31963600#31963600) if you want. – AJ Henderson Aug 28 '16 at 18:57
  • @AJHenderson I don't think you'd want the server sending the salt to the client. Salt helps protect against the shotgun approach, determining the password for many users at once, if the database is compromised. It doesn't help defend against an attack against a single user. Leaking a user's salt publicly to anyone attempting to log in with that username would slightly decrease their overall security. – lordcheeto Jul 02 '18 at 05:42
  • @lordcheeto how? Without the database data, an offline attack isn't possible. Having the salt without the hash is of zero value to an attacker. This is why the salt isn't considered secure data. The DB must know it and if the attacker doesn't have the DB (or atleast the hash), it is completely useless information. If the client itself is compromised they can simply key log. – AJ Henderson Jul 02 '18 at 12:36
  • "*If the server is ever compromised, the attacker would immediately have access to all user[s]*" Woa, big surprise! Someone who owned the server can actually access things on the server! Sarcasm aside, I feel like this answer does not highlight the right things. Sure, one should do a fast hash on the server, but why else do we bother with slow hashes and salts if not for the user's protection? Client-side hashing has [many advantages](https://security.stackexchange.com/a/201099/10863) and I consider preventing a login to be a nice side effect that is by no means essential for system security. – Luc Jan 09 '19 at 23:28
  • @Luc - not all breaches involve total control. If just the user table is accessed in a readonly mode, all users would be breached fully. If the hashing is secure server side, there would be a sizable effort per user still in order to be able to compromise the system further. Perhaps just an offline backup server is compromised or a backup on a development laptop is stolen. It's foolish to only expect all or nothing breaches. A slow client side hash is trivially bypassed as the client side can be skipped and simply enter the result the server expects instead. – AJ Henderson Jan 10 '19 at 00:15
  • @Luc - note that I actually agree with your answer on the other question as it is dealing with an application. In the case of an application, it's at least slightly harder to bypass the additional hashing to skip straight to the intermediate password, so there is some value, but this question was talking specifically about websites where it is trivial to skip to the intermediate password. All client side hashing does for a website is make a password derived password and a slow hash is no more effective than a quick client side hash or a password derived key. – AJ Henderson Jan 10 '19 at 00:19
  • @AJHenderson By it being trivial to skip to the intermediate password, you mean that an attacker would just modify the server's code to stop it from sending the necessary JavaScript to the client, so that the client submits the password instead? In that case, see the FAQ at the bottom, it's an argument I frequently see and I just don't think it's enough to negate all of the advantages. – Luc Jan 10 '19 at 00:39
  • @Luc - your FAQ is wrong when it comes to websites. Comments aren't a great place for extended discussion, but to be brief, slow hashing ONLY matters if the hashes are compromised (thus the DB is compromised) if the server isn't compromised, things might as well be in plain text as long as channel encryption is in place. The point about a browser extension is completely irrelevant as the attacker is not attacking the user's machine, but rather the web tier. The chances of having a limited incursion, especially when there is decent IDS, is actually quite high. – AJ Henderson Jan 10 '19 at 01:58
  • If things that shouldn't be writing to the DB start writing to the DB, something is going to notice, but there are many possible ways that read only hash lists could be exfiltrated. It would then be possible to start working on compromising accounts for either changing things in the system or looking for matching credentials on other services. That is the much more realistic case and client side hashing isn't going to do much to help. It has value for password extension, but that's all it's really accomplishing. – AJ Henderson Jan 10 '19 at 02:07
  • SSL HAS NOTHING TO DO WITH CLIENT SIDE HASHING. Client side hashing eliminates the Password Policy and eliminates the threat of server leak password cracking assuming the server also hashed the clientside hash. – 8vtwo Aug 09 '21 at 05:50
  • @8vtwo - yes, and? I'm not sure how you think SSL is related to this answer, other than the bit pointing out that client side hashing provides no transmission security improvement. I went in to other detail about how it doesn't protect against a compromised server either. The only thing it does is allow an extension of the at rest brute force cracking efficiency as you could use an expensive hash to make bad passwords a bit less bad. This is mentioned in my original answer. (6th paragraph) – AJ Henderson Aug 10 '21 at 21:48
  • @AJ Henderson Comment was definitely meant for the answer above this one where I read "as compared to SSL it has a number of weaknesses" (WTF?!) and I went nuts and scrolled too far. – 8vtwo Aug 11 '21 at 06:53
  • @8vtwo - ah, that makes more sense. :) – AJ Henderson Aug 11 '21 at 18:48
22

If you have quite a few advantages, then you should list them in your question so that people will find out whether they are truly useful (and you may become famous if so ;)

People don't favor client-side hashing because they have better ways of protecting users private information. Let's think about the places with potential information leaks and there are three of them:

  • The client.
  • Between the client and the server.
  • The server.

Then let's see why or why not client-side hashing will help in these places.

  • The client.

    If there are malwares on your own computer, for example, if your browser is compromised or your computer is implanted with key-logging software, client-side hashing doesn't prevent a hacker from getting your password. The reason is obvious.

  • Between the client and the server.

    There is the communication channel between client and server. If there is an eavesdropper listening for the communication, then client-side hashing can make the leak of password more difficult because the eavesdropper has to recover the original password from its hash. It's indeed useful here.

    However, this vulnerability is based on the presupposition of an insecure communication channel. In reality, there are protocols whose existence tries to solve this problem exactly. Their major task is to establish a secure channel over an insecure one. The most famous and widely deployed example is SSL/TLS, and it provides more functionality and better security than client-side hashing.

    The conclusion is that client-side hashing is helpful in the channel, but here are better tools.

  • The server.

    Users information may be leaked on the server if the server is compromised by a hacker. The hacker can fetch user passwords from database if they are stored in plaintext. That's why today most servers don't do that. Instead, they store hashes of passwords so that hackers can't easily restore the original passwords from their information at hand (i.e. hashes).

    You may be tempted to believe things still work well if the server simply stores hashes computed on the client side. But this is severely wrong. In that situation the hashes themselves become password equivalents. The hacker can pass authentication by simply handing over the hash without reversing it. The goal of a hacker is not reversing a hash, but breaking into your account. The importance lies in the server's verification process on client data, not on the fact that the data is a hash value. Therefore the benefit of client-side hashing is trivial here and the server must rehash anyway.

To summarize, client-side hashing is helpful in protecting user information, but the protection largely applies to the communication channel. Since we have better approaches there (SSL/TLS), the application of client-side hashing is greatly surpressed. It's simply not the best tool for the task at hand.

Cyker
  • 1,613
  • 11
  • 17
  • 27
    Re: this statement: "The goal of a hacker is not reversing a hash, but breaking into your account." I would say that depends on what the site is. Oftentimes the user's password is more valuable than access to the site, with the hopes that the password may be used on other sites where gaining access would have more value. – TTT Nov 29 '16 at 15:00
  • @TTT From its context, this sentence actually means the hacker doesn't care about whether it's a hash or a plaintext password as long as he gets the private information he wants. – Cyker Nov 30 '16 at 02:39
  • 1
    This answer is super helpful. – NDiaz Nov 30 '16 at 19:31
  • 7
    I agree with TTT. I disagree that it is "better" (as you've said) for the client to send their password in plaintext instead of a salted hash. This opens up the risk that some server-side agent steals or leaks the client password, either by malicious intent or negligence. Since many users re-use password cross-side, it's a very concerning risk. – Jay Sullivan Dec 24 '16 at 02:32
  • So the summary of your answer is "because I see only slight advantages"? Not because there are any disadvantages of doing only a fast hash on the server and the slow hash on the client? I elaborated a little on the topic in [this answer](https://security.stackexchange.com/a/201099/10863) and am curious to hear your thoughts. – Luc Jan 09 '19 at 23:30
  • @Luc The idea is that the server uses whatever passed by the client as proof of identify, whether it's a hash or not. The server simply views it as a plain string and the server must do its own job to protect this string from being recovered by the malicious. If the client feels it needs to protect its password against a malicious server or vulnerable communication channel, then it is free to do so. But that's not the web server's job. For example, the client can use a random password for each site and no hashing is needed. – Cyker Jan 09 '19 at 23:54
  • 1
    @Cyker Yep, if everyone would use a password manager with unique, random passwords, we would not have to have this discussion! But that's just not the case, we all know how frequently sites get hacked and that the data is used to hack the users on other sites, where they re-used their password. It's indeed not your job to protect the user, but neither is it your job to fix water in Africa. Still, countries that can afford it pay development aid (and in democratic countries, people collectively agree on it). We help other people where we can, so if we can just hash in a better spot, why not? – Luc Jan 10 '19 at 00:07
  • @Luc For *hash in a better spot*: What makes you think hashing on the client side is better than on the server side if the channel is secure? If you are using plain HTTP then you should move to HTTPS instead of relying on your own client-side hashing. – Cyker Jan 10 '19 at 00:18
  • @Cyker See the link I posted earlier: https://security.stackexchange.com/a/201099/10863 There are lots of advantages to client-side hashing, all of which assume the transport channel is secure (you just reminded me that I forgot to mention the case where the transport channel is compromised!). Full agree on that https is much more important than client-side hashing, by the way. If you don't have https, there are way bigger issues. – Luc Jan 10 '19 at 00:26
  • @Luc Well if you think client side hashing is helpful in your specific use case, then you are free to implement it. Provided you are using a sane hashing algorithm, I don't see how it becomes harmful except wasting some resources on the client machine. For example, if you think the client machine is more secure than the server machine because there are some sour employees intercepting user data on the server side. Don't forget to salt the hash in that case. – Cyker Jan 10 '19 at 00:35
  • @Cyker Salting, yes, thanks for reminding me to add that. People should indeed not forget to do that. – Luc Jan 10 '19 at 00:41
  • NOBODY IS SUGGESTING THE SERVER STOP HASHING PASSWORDS. ALL YOUR OTHER POINTS ARE FRIVOLOUS. CLIENT SIDE HASHING PROTECTED STORED PASSWORDS AND REMOVED PASSWORD POLICIES. – 8vtwo Aug 09 '21 at 05:55
8

It is good practice to hash on the client side, then salt the password and hash again on the server side. This is an extra layer of protection against man in the middle attacks. SSL is the first layer however Snowden's revelations made it clear that SSL can be compromised by organisations such as the NSA with relative ease.

  • 5
    This answer provides nothing that the other answers don't, and misses the point that to a MitM, the client's hash of the password can be used as if it were the password itself. – Mark May 05 '15 at 08:29
  • 4
    @Mark Um no Mark. This does indeed help with mitm. Mayhem is stating at hashing the hashed password yet again. – Karl Morrison Jan 28 '16 at 22:02
  • This is a good idea I haven't thought of. Hash on the client side to hide the plain-text password, then hash on the server side to protect from a server-side breach. Thanks for sharing! – Aaron Gillion Apr 15 '16 at 23:55
  • 1
    @Karl, The 'man in the middle' would still be providing the same request parameters as the target user. Just because it isn't a password, doesn't mean the attacker can't intercept the hash and provide that same hash on to the server (to let it "hash the hash" and succeed at a match). – zyglobe Oct 26 '16 at 03:25
  • 1
    @RedGlobe That however is true. But it does help, because a looot of internet users use the same password for everything. I agree it might not help against that particular system, but it will help on a broader scale. – Karl Morrison Oct 26 '16 at 08:48
6

What advantages would client-sided password hashing have?

Well, the password wouldn't be sent over the net in clear-text. But you should really be using TLS encryption when you log in, so password sniffing should not be an issue.

Another reason could be that you don't want the server to ever be aware of the users password, not even for a microsecond. That means you give the server the password hash on registration and then log in using that password hash. Unfortunately this doesn't solve anything: The shared secret to log into the account is now the hash, not the password. When you obtain knowledge of the hash, you can log in without knowing the actual password (because the server doesn't know it either).

Philipp
  • 48,867
  • 8
  • 127
  • 157
  • 2
    The advantage for me would be that I can use the user's password to encrypt some local data in my app, and proof that the server is never able to decrypt that data (since it only knows the hash). Otherwise I would have two prompt the end-user for two different passwords (1 for login, 1 for encryption). – Maestro Mar 18 '14 at 13:41
  • @Muis In that case the answer would be "Because nobody has such exotic requirements like you do". – Philipp Mar 18 '14 at 13:54
  • @Muis, your definition of "proof" must be weak as often knowledge of the hash is equivalent to knowledge of the password since dictionary attacks are so successful. I do see your point though. It is proof if the user picks a good password. – mikeazo Mar 18 '14 at 15:30
  • @mikeazo I salt the hash, so dictionary attacks are useless. – Maestro Mar 18 '14 at 15:53
  • 10
    @Muis That's not how salting works. Salts only protect against precomputed rainbow tables, not against dictionary attacks. – Philipp Mar 18 '14 at 16:01
  • 2
    @Philipp, salt does guard against dictionary attacks where the attacker just wants one out of many captured hashes. It does not help against dictionary attacks on a single hash. – mikeazo Mar 18 '14 at 16:53
  • 1
    @muis in that case use a private symmetric key that is password protected. This will generally provide far better security for the encrypted data due to the higher entropy of the symmetric key while also ensuring that the server does not have the ability to decrypt (as it does not have the private key). Don't roll your own... use established and known secure patterns. – AJ Henderson Aug 28 '16 at 11:12
  • @Muis Using user password to encrypt local data may not be as good as you think. What happens if the user changes it's password? Also, if the server has the data to encrypt it with the user password, then the server doesn't need to decrypt the data, it already has it, so you can't proof that the server is unable to access the data (Which is the point of decrypting it) – Mr. E Nov 30 '16 at 15:42
  • -1 very short-sighted answer. Sure, what you transmit to the server is equivalent to your password. That is always the case. But it protects the user a lot better to hash it before transmission (TLS has its share of issues) and especially before it arrives on the server (where the real vulnerabilities usually happen). – Luc Jan 09 '19 at 23:38
3

Though the topic has some concrete leak points, as pointed out by @Cyker, the discussion is a little brisk here ... I'd like to add one point that I didn't see mentioned.

It's simply that if you hash ASAP, then you reduce the programming risks of accidentally passing a clear text password somewhere that it shouldn't go. We already take measures like secure strings and secure arrays to try to destroy the clear text ASAP; and hashing at the moment that you get the password is another measure like that ... As code evolves, etc. the risks seem to still be reduced.

I just wrote a little C# "Box" that takes the SecureString clear text and hashes it immediately --- this way I simply know that it will never be logged or passed to a library I don't expect. This is not so much about a protocol as it is just the programmer here sitting and looking at a password --- I don't wan't to touch it! (It's still a password equivalent in some aspects, but it is at least immediately concealed from folly like moving a closing parenthesis in a chained method call and passing clear text to the wrong place. And a secure array is still not concealed.)

Steven Coco
  • 131
  • 1
3

Since you are talking about web application...

In a database we have a table call dbo.useracc we are storing these hashes password

User        Password
--------       ----------
user1       5f4dcc3b5aa765d61d8327deb882cf99
user2       202cb962ac59075b964b07152d234b70
user3       098f6bcd4621d373cade4e832627b4f6

and our login function in web application be something like

if (user == $user and password == $pass) {
           return auth.token
}

Let's say an attacker successfully hacked and stole the database and saved our dbo.useracc data. He now has our hashed password.

If your login hashes process is stored in the client, the attacker can still accesses your account with the hashed password by just hooking up the HTTP POST method altering the password field to send your hashed password and he is still able to login. Remember your application data are communicating with the server through the POST method eventually after it's hashed to be checked against.

However if the hashing process is in the server, it's another story.

$pass = md5.hash($pass);

if (user == $user and password == $pass) {
           return auth.token;
}

If the hacker use the hashed password to login, it will be a hash 'hashed password' checking against a hashed password.

In this case let's say the attacker post

$user = user1 $pass = 5f4dcc3b5aa765d61d8327deb882cf99

After the server side doing $pass = md5.hash(5f4dcc3b5aa765d61d8327deb882cf99) it will return '696d29e0940a4957748fe3fc9efd22a3' which is returning a false statement.

This is to fence off attacker who has successfully stolen the database data and trying to access through the web application using the hashed password. And of course the attacker still can hack into the accounts if they successfully bruteforce / crack the hashes through dictionary attacks and so. However the hacker requires longer time if the password is a good password after compromising the system and the server admin could just reset the password and email the users.

Also it is also used to internal threats like employees in an enterprise. In an enterprise, there will be Database Administrator and Developers. They are different roles. Now to prevent the employee users to access to the sensitive data, they need to have access to both application and DB to get access to the data. Of course you might argue a DBA can still alter the database data through the database itself, but it is not accessible by the developers and it is easier to pinpoint where is the attack from. It is about access control rights and minimizing the risks and threats.

Sky
  • 234
  • 1
  • 5
  • 1
    You're correct that it doesnt make it harder for an attacker to enter MY site using the stolen hash, but it makes it harder to login to ANOTHER site, since the other site most likely dont use exactly the same salt + hashing algorithm. – Maestro Mar 18 '14 at 14:04
  • There's no way the attacker can access ANOTHER site with the hashed password too as long as the ANOTHER website don't practice hashing in the client and is a good password that is hard to be bruteforce by dictionary or rainbow table attacks. And as a developer, why would you even care about "ANOTHER" site in the first place. If the users value their other data a lot, they should practice not to use a global password instead. – Sky Mar 18 '14 at 14:11
2

I agree that if SSL/TLS is available the advantage of client-side hashing to protect the authentication process is limited. However, SSL / TLS does not resolve the vulnerability to custom hardware attacks if the attacker has access to the stored hashes (AFTER the process). Functions such as simple salted hashes or schemes like PBKDF2 are very vulnerable to these attacks because of their low memory requirements. The cracking of passwords, protected with theses schemes is cheap and fast. And that is at least one of the main problems of password hashing.

At first glance, this has nothing to do with client-side hashing versus SSL/TLS - but: When a sever implements a memory-hard password hashing scheme such as Scrypt, Argon2 or Catena to protect custom hardware attacks, the server‘s hardware requirements increase dramatically. In reality, services therefore reduce the memory-hardness or switch to vulnerable schemes. Client-side hashing helps a bit to get around this problem. When the clients compute these expensive (memory hard) functions, the service can use them without the need for better hardware.

Modern password hashing schemes therefore offer the possibility to delegate the most expensive (memory-hard) parts of the function to the client. This feature is called server relief and is offered by Argon2 and Catena.

Conclusion: Using modern password hashing schemes, which are much less vulnerable to custom hardware attacks, will increase or at least should increase the use of client-side hashing in the future – of course along with SSL/TLS.

BeloumiX
  • 246
  • 1
  • 5
2

Most websites send the password as plain, or base-64 encoding (basic auth), and rely on the TLS layer for hiding the password. This is common practice, and is as safe as the TLS layer is really secured.

But TLS is not perfect either. In practice, most corporations include an Interception Proxy in their security chain. They added their own root CA to the corporate client devices, and actually intercept outgoing TLS requests, for security or regulatory reasons (e.g. log, monitoring). So the password is plain not only on the client and server side, but also at the interception proxy level.

We should therefore not rely on TLS for truly hiding sensitive information. Client side hashing seems mandatory if you expect a truly secure use of your secret password.

In addition to plain password hash, you may consider for additional security, and to avoid replay attacks:

  • To include a server-side challenge: server sends random A, client hashes A + password and sends this value;
  • To include server-side and client-side challenges: server sends random A, client computes random B, client hashes A + B + password and sends both B + hash;
  • To include a client-side puzzle (blockchain-like proof): server sends random A, client loops computing some random B and hashing A + B + password until the hash starts with n zeros (the bigger the more computer intensive), client sends B and it is easy and cheap for the server to verify B.

Proven protocols always include client-side and server-side challenges, to avoid replay attacks. Hashing and challenging is uncommon on WebSites because:

  • Client-side hashing is slow if done in plain JavaScript, so the most sophisticated proven means like client-side puzzle may be quite resource consuming - even JITted hash computation is far behind optimized OpenSSL library code for instance.
  • It is not trivial to implement a proper authentication protocol, so most developers rely on the well-known TLS layer for the security. Reinventing the wheel is not a good idea in a security context.
  • Security Auditors don't like custom protocols. They prefer to have a known TLS, and check the WebServer settings, e.g. the TLS versions and enabled ciphers list. It is easy to verify, even if not fully secure.

On a corporate level, you may consider using a proven authentication algorithm like Kerberos/Negotiate, and a domain controller, then you will have a known client-side hashing with server-side and client-side challenge, and other benefits like single sign-on, and - most of all - centralized user management for authentication (even if authorization could be delegated at the web application level).

Security Auditors would easily recognize and validate it, and your manager would like the fact that the development cost is low, if the server is part of the domain controller. You may consider securing your most valuable resources using this authentication, and only allowing basic authentication for the main/insensitive parts of your website.

1

I'm going to jump in here with the express purpose of weighing in favor of the client-side hashing mechanism. Let's see how this benefits us:

Client-side: No improvement.

In transit: Protects the password in case of SSLstrip in which the password ends up being transmitted in cleartext. However, if HSTS is implemented, then most people would say that SSLStrip would have no effect. Right? No.

On entry to the server: Finally, we see the major benefit. What happens if someone has compromised the server? They get a continuous flow of cleartext passwords if they just boot up Wireshark/TCPDump and export the server's private key. Now they can sit on the wire for a couple of months, and for high-volume servers (millions of user registrations per month), they get their massive plaintext breach. This is assuming that it is more valuable to grab the passwords for the people on the service than to have RCE on their server, of course.

On the server: Performance benefits if it doesn't have to run bcrypt on every incoming password, which offloads some computational cost onto the client without introducing any new vulnerabilities. This seems to be a good thing for your server's administrator as well as your hardware costs.

Still, it looks like best practice would be to incorporate password hashing into the client side unless it creates unbearable page load times for the users.

DeepS1X
  • 321
  • 1
  • 5
  • I am curious to hear why someone downvoted this answer. SSLStrip is a little dated, but not wrong, and the rest of the answer sounds accurate to me. – Luc Jan 09 '19 at 23:33
  • I certainly don't know. Re-reading my commentary from several years ago, I can't see any obvious flaws in my reasoning. – DeepS1X Mar 13 '19 at 06:03
0

I think client-side hash has one upside and one drawback:

pro : You hide the password in case of dns/phishing/whatever, which is useful for the user, since most people reuse passwords on several service. As other devs said, this does nothing for your own security.

cons : Your server does not get the password, which prevents stuff like warning the user about password strength. I know some will say this can/should be client-side, but when you have multiple clients, this can be nice to centralize server-side.

savvy
  • 11
  • 1
    (I did not downvote, would be nice if people could explain downvotes.) Password advice should really be done client-side. I would recommend a library like [zxcvbn](https://github.com/dropbox/zxcvbn) which is available in many different languages and seems very goal-oriented and well-designed. That would also limit having to incorporate the advice in all clients' code separately. – Luc Jan 09 '19 at 23:34
-5

i think the probability of being hacked in client-side is more higher than that in server-side. (Because there are some IT expert look after the server) . if your computer is already being hacked. the client-side 's algorithms which used for hashing your password also can be stolen by hacker . Aso soon as your algorithms is no longer a secret. i think,it become useless.

  • 4
    We generally frown on secret algorithm (See [Kerckhoffs's principle](http://en.wikipedia.org/wiki/Kerckhoffs's_principle) and security-through-obscurity. Password hashing certainly doesn't need to rely on this. At most we apply a key and hope that the attacker doesn't find even if they manage to steal the database. – CodesInChaos Mar 18 '14 at 11:03
  • 1
    The "server is more secure" argument makes little sense in this context. 1) The client knows the plaintext password, so a trojan can trivially steal it with a key-logger. 2) Password hashing only offers an advantage over plaintext passwords when the server gets hacked and the database gets stolen. – CodesInChaos Mar 18 '14 at 11:05
  • 4
    The way twitter works is that you follow people whose tweets you find interesting. No need to ask for permission. – CodesInChaos Mar 18 '14 at 11:20
  • 1
    A server with all its user data is a way more valuable target than one single user. – Gumbo Mar 18 '14 at 14:33