12

One of the companies I worked for used client-side hashing to minimize risk when logging the password in the server logs. Can this be a good reason to implement client-side hashing?

9
  • 35
    Why log the password at all? Now, the hash is the password. Jul 6, 2020 at 0:49
  • 13
    Contrary to what everyone is saying, having the client hash the password (along with the server hashing the hashed password) can prevent an attacker from recovering the plaintext password to try on other sites. You'd still need to take the same precautions with the hashed password as the regular password.
    – user
    Jul 6, 2020 at 15:01
  • 2
    @user contrary to what you're saying, I specifically addressed that in my answer. Jul 6, 2020 at 15:06
  • @user but ideally that is something the user defends against by avoiding password reuse. Jul 6, 2020 at 15:09
  • 5
    Are they doing this because they believe it's safe to log the hashed password? Or are they doing this defensively, in case some intermediate system inadvertently logs the hashed password? Once you've integrated a bunch of different telemetry and error capturing services, it's too easy to accidentally log entire HTTP request bodies. It's not OK to do that on purpose, but if you want to minimize the damage if it does happen, hashing the password on the client is a reasonable precaution. But, you're obligated to treat that hash just as securely as you treated the plaintext password.
    – user229044
    Jul 7, 2020 at 0:48

7 Answers 7

20

Almost never.

As others have pointed out, this just replaces "SECRET" with "HASH(SECRET)". To make things worse they log the hash, which is now the password.

This is because the client is authenticated on the basis of the hash it transmits, alone; so, knowing this hash either by intercepting it at the client level or by lifting it off the logs, one can access the service at any future time until the secret is changed.

These two things together negate all logging security and create a problem (you are now logging "data, including personalised security credentials which can be used to carry out fraud", and this impacts your PSD2 compliancy).

Having a different hash on the client (for logging purposes) and on the server (for authentication purposes) would be tricky to implement, since the server guys would have no quick way of verifying that the hash is indeed correct, unless they knew the password (which would have to be stored in the clear somewhere). Using the same hash or a two-level hash might be used, I don't know, to diagnose whether the password was sent correctly (the client sends both the pass and its hash, the second gets logged and is the same as the hash stored in the auth records, or is the hash of that hash just to complicate things) -- but unless things go very wrong, this information is the same as the login status.

A better way to do this would be for the server to send a unique ID plus a timestamp, and for the client to hash together the password, the unique ID and the timestamp. The server could then send ID, timestamp and username to a black-box "oracle" that would only answer yes or no (or "OK", "NO SUCH USER", "BAD PASSWORD", "TIMESTAMP EXPIRED", "UNIQUEID REUSE DETECTED" and so on). This way:

  • the server does not know the password (the "oracle" does)
  • the log can safely contain both unique id and timestamp
  • the hash cannot be reused (the timestamp would go "stale" after some time)
  • the password never travels in the clear, only the hash does
  • unique id and timestamp act as salts of each other

You might be interested in looking at thinbus-srp.

8
  • 3
    SRP is a good approach in many cases. But we should keep in mind that the service side in such scheme cannot enforce any password policy: how often user changes the password and if changes it at all, password, length, password complexity. Everyone decides if this is important in particular case.
    – mentallurg
    Jul 6, 2020 at 16:31
  • 1
    @mentallurg: A hacked client can always ignore password complexity by ghetto-implementing client side hash or worse.
    – Joshua
    Jul 6, 2020 at 23:44
  • 1
    @Joshua: It was not the point. I mean that it depends on the context. If users do really care about their safety and event don't want to trust the server, then SRP is very good. In such case not server side, but users will require using such scheme. But there are also other cases when users are less skilled and it may be reasonable to enforce some password policies. Then SRP may be not the best choice.
    – mentallurg
    Jul 7, 2020 at 2:47
  • 2
    "These two things together actually negate all security" - If it negates all security, then it would be equivalent to not having a password for the service in the first place, which clearly isn't the case. Secondly, who ever said that client-side hashing is the only hashing involved? Thirdly, in most cases, someone with access to the server logs can usually manage the service anyway, so trying to hide hashed login creds from sysadmins is like hiding bread from the toaster. I agree that logging creds in any form is bad, but that is an issue separate from additional client-side hashing.
    – Luc
    Jul 7, 2020 at 11:43
  • I don't understand why hash of a password is a password. If server hashing is different from client hashing, one hash can't be easily used to hack another.
    – Basilevs
    Jul 8, 2020 at 6:54
11

Sending hash instead of password does not solve the problem with logs. If an attacker get access to logs and can read hashes, then knowing password becomes not necessary. In the login request the attacker will just send the hash retrieved from the log. The server will not know if the client has password and created a hash, or if the client knows only the hash.

0
3

No, that's not a good reason:

This never helps. This architecture just replaced the secret "password" with the secret "hash of password". Neither can ever fall into the wrong hands, because the hash is sufficient for logging on. (You can never assume the client has unmodified software. A simple debugger is sufficient to make a client program send whatever you want.)

And they're logging these hashes, which they simply shouldn't do, because now they've got a plaintext log of all the credentials necessary to log on.

The issue at hand is the overzealous logging, not the passwords.

Plain hashing, as far as I can tell, also doesn't ever contribute any further factors into the credentials, so I only see very strange use cases where it might be helpful (for example, to avoid password reuse vulnerabilities should the server be compromised—but if your user reuses passwords, then your server being compromised should be the least of their worries). Instead, I often see it used as snake-oil ("magical cure") for security issues that are much more severe but people try to distract from—exactly like this logging issue, or things like unencrypted database connections.

7
  • 1
    Doesnt client side hashing, with the act of authentication being the comparison of the hash result and the stored value in the authentication store, mean that the act of salting the value in the authentication store is now meaningless because you are comparing given hash (created clientside with presumably the salt) to stored hash? Which means the authentication store basically has all the authentication tokens in plain text for anyone to steal? In other words, how do you know if the client is actually hashing a provided value or just giving you a stolen hash?
    – Moo
    Jul 6, 2020 at 3:55
  • @Moo exactly, you don't So, no advantage to hashing – exactly what my last paragraph tried ot explian. Jul 6, 2020 at 9:03
  • 3
    We found on analysis this does in fact help. A backdoored server can't steal the user's real password, and if each has the password client-hashed with the hostname as salt, the server can't even steal credentials that can be used on another server.
    – Joshua
    Jul 6, 2020 at 19:14
  • 1
    @Moo: If all hashing is done on the client, that would indeed be the case. On the other hand, if the client is sent a salt and then asked to perform some slow hash operation that yields a 256-bit hash value, which then be fed through a secure but fast cryptographic hash, someone wanting to brute-force the server would have to search through a space of 2^256 equally likely has values, rather than searching through a space of low-entropy human-readable passwords. I would think such an approach could mitigate denial of service attacks by reducing the effort required for each access attempt.
    – supercat
    Jul 6, 2020 at 20:02
  • 1
    "if your user reuses passwords, then your server being compromised should be the least of their worries" -- but the reality is users do reuse passwords, even if you ask them not to. Might as well remove one of their worries, even if it's the least one. Jul 8, 2020 at 13:12
2

It won't help the client, as many others have said, because hash(password) is enough for a malicious party gain unwanted acess. But at least password won't end up in a wordlist, if the server is hacked and all the logged hashes become public.

2

First let me say that you should never ever be logging passwords, but it seems from the question that the company you worked for was worried about inadvertent logging. Maybe they have some kind of logging software on their server that stores all communications including when you send the password.

Simple hashing offers a very small level of gain. As others have said if your client uses the hash to login, others could use the has as well, so what's the point? The very small gain in security is that you won't automatically expose the raw password. This would only help if:

  1. The password is large enough to prevent discovery from the hash (using rainbow tables or brute force for instance)
  2. The password is changed regularly (hash would only be usable for a short time)
  3. You log the passwords WHICH YOU SHOULDN'T EVER EVER DO, but from your question it seems you are worried about an accidental occurrence or if some third party or crash/error reporting software logs it carelessly

First: If someone nabs your log file and you have plaintext passwords in there, it's just game over. Some software might log what is sent to the server without your knowledge and the log file might be placed somewhere it shouldn't be. Yes, in a perfect world this would never happen, but some temp or tech support person might run across such a file some day. If there are plaintext passwords in there, the amount of work to do something malicious is just so small it could tempt people that would never dream of cracking hashes or writing software to use your system with a hash. "My manager's password is there? I'm just going to login to our email client with his information quick and search for my name for what he's been saying about me..."

Second: If passwords are changed regularly, an uncrackable hash would be worthless in a few months, or on other sites. Many people only make minimal changes to their passwords though, and re-use them on other sites. So if your software that uses client-side hashing exposes your application because the hashes can be used, the same hashes probably can't be used for other purposes such as email or authentication to network shares or other intranet sites. Some people probably have the same or similar passwords for other sites online like personal mail, amazon, banking, etc. It's bad practice, but that's what a lot of hackers rely on. If you see the password three months ago is 'Fluffy#$Kitten7', you might try 'Fluffy#$Kitten8' next since many people make minor changes to their password when they are required to change it frequently. The hash would be completely different for the new passwords so the old one would be invalid.

0
2

You have two issues here: logging sensitive data in plain files, and password hashing.

Logging sensitive data

Don't do this.

This includes passwords, other security tokens (session IDs), racial or other data labeled as sensitive under GDPR or your local jurisdiction, and other data that sysadmins don't need to help in debugging.

If you have a stupid manager that overrules you, then look into encrypting the data with a public key. The private key can be kept somewhere safe, like in a safe deposit box or some offline system. If you ever need access to the data, you can get it, but there is very little risk of anyone else decrypting that data.

Specifically for passwords: if you are going to hash them anyway, then why log it in the first place? Apparently nobody wants access to the plaintext version of it, and to reset a user account you can reset the password value in the database. There is no reason to log hashed passwords.

Password hashing

To see whether client-side hashing is helpful, define what the risks are and follow the logic.

You mention an insider threat, but who is that insider? Can they only read log files? Do they have database access? Can they change the code running on the server?

  • If the insider can only read log files, then client-side hashing would help. If the user uses Fluffy1992! as password, then hashing prevents the insider from knowing that, so the insider can't try to login to other accounts of this user. But like others pointed out, they can login to the application by submitting whatever the original user submitted (a replay attack; this can be prevented with a challenge-response system).

  • If the insider can also access the database, there would be no reason for the insider to login to the user account: they can already see and modify everything the user can. Hashing still helps not to reveal the kind of password that the user used, so it's still helpful.

  • If the insider can also change the code that is running on the server, then they can change it such that the client is instructed (through a modified javascript file or malicious update) to also submit a plaintext of the password. This is extra effort and might be spotted by other visitors of the website, though, so client-side hashing would prevent opportunistic reading of passwords and feel more risky, but not actually deter a determined person.

Note that the server should always apply a quick hash to the hash that the client sends: if someone gains read-only database access (e.g. SQL injection in a select query, or a stolen database backup), they can read the password hash from the database but still need to break it. Without applying the hash on the server, they could take the database value as password. So the client should do pwhash = bcrypt(password+salt,cost); send(pwhash); and the server should do store_in_database(sha256(pwhash)).


Since your question is about logging the hash, I think the simple solution is not to log sensitive data, as said. Nevertheless, client-side hashing is not a bad idea if you also apply an additional hash on the server. Client-side hashing helped mitigate other security issues in the past, but if it had been more common, it would have prevented many more.

16
  • "The server should always apply a quick hash to the hash that the client sends" - no, the sever should apply a slow secure hash (e.g. bcrypt) to whatever the client sends, to deal with the important threat (the database leaks and an attacker tries to get credentials from it). It's the client side hashing that can be less secure, because the threat there is less important (it's vital to do server-side hashing but many people don't do client-side hashing). If an attacker has the client-side hash then that already lets them authenticate as the user, which is usually the main thing we care about.
    – rlms
    Jul 7, 2020 at 22:08
  • @rlms No, the client should apply a slow secure hash (e.g. bcrypt) to whatever the user enters, to deal with the important threat (the database leaks and the attacker tries to figure out users' credentials). If you have database access to read stored credentials anyway, you already have the kingdom, why care about the keys to it? It is definitely not the main thing I see as a threat since credential re-use is so much more prevalent and impactful than accessing the application after completely owning the database.
    – Luc
    Jul 8, 2020 at 7:24
  • Also, fast server-side hashing is not less secure because the token is already strengthened on the client. A slow hash makes it harder to crack a weak password: after strengthening, there is little point doing another slow hash on the server. If it sounds theoretical, try it: here's a client-side bcrypt of a bad password (3 words no spaces, ~48 bits of entropy): $2a$12$uGO0B0bnWhrFmonzpVrHbehy6woBE6dTMRRUuwopBxirRLWb0TsiW and here's the md5 of the hash part (hy...): a25d5f675a6780eb7bccf435c934d6b4. If you stole the weak md5 from the database, can you get to the former so you can login?
    – Luc
    Jul 8, 2020 at 8:57
  • The point is that you don't need the actual password to log in, you just need whatever the client sends, because you're a l33t hacker (i.e. you can use curl to send requests with hashes to the server rather than typing in the password on the client website). If the data the client sends to authenticate is leaked (whether that's passwords or password hashes) you've already lost.
    – rlms
    Jul 8, 2020 at 13:16
  • The client applying "a slow secure hash (e.g. bcrypt) to whatever the user enters" does not "deal with the important threat (the database leaks and the attacker tries to figure out users' credentials)" in any way!
    – rlms
    Jul 8, 2020 at 13:18
1

It does not, proper hashing requires iterations and salts, which with client side hashing can't be achieved (e.g. without the system knowing the salt and actual password it can't verify it). If you are just doing a normal hash, then you just replace the secret like Marcus is pointing out.

However the proper way of fixing is - is to use tokenisation or sanitisation of passwords within the logs, rather than using hashing. Tokenising and sanitising should be done for all sensitive fields ideally.

1
  • The salt is not secret, so this can't not be achieved. The client could ask for the salt or the salt could be serviceName+userName. Client-side hashing isn't rocket science (in fact, earlier today I was recounting to a friend how it saved my ass that SMF forums do client-side hashing and prevented people with my session token from invoking admin features). Of course, I do agree with the second part about simply not putting sensitive data in log files.
    – Luc
    Jul 7, 2020 at 11:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .