1

I have read a few articles and several question on here about hashing correctly. While hashing, adding salt and especially pepper is primarily a server side use case, I am interested in the possibility to implement (not talking of inventing security mechanisms myself) as much of these practices in a JavaScript based web application (client-sided) additionally to the server side.

Hashing

...as answered by many questions before, is totally possible on the client side but still crucial on the server-side to not replace the hashed password with the client hash itself. Additionally the password is protected in case of a compromised server. An attacker who gets hold of it due to an insecure connection has to use a rainbow table to find out the password instead of clear text.

Salt

...has to be unique but not necessarily more private than the hashed password itself, is stored in the same database. Like-wise a client salt could be the unique user name, however salting is irrelevant to the attacker if the user is send in clear text in addition to the hashed, salted password. (But without the user name, the salt does provide additional security.)

Pepper

...has to be secret, is shared for all passwords in an application and kept separate from the database containing hash and salt (e.g. in the application as the application might not be accessible for an attacker who did an successful SQL injection in the database). If the JavaScript of a web application included a hard coded pepper, the attacker would easily find it out and therefore make the pepper useless.

(Again: assume the server side to hash, salt and pepper no matter of the actions on the client side)

Is there any way to pepper on client side to increase password security while transmition? I have no experience in security and can not think of a way to include such a pepper safely since the attacker can be the client or fetch the server's traffic including the client's pepper.

Alex Probert
  • 493
  • 1
  • 3
  • 17
  • When you say "salting is irrelevant to the attacker if the user is send in clear text in addition to the hashed, salted password", do you mean that salt is useless when it is known to the attacker? – Luc Mar 27 '19 at 08:28
  • @Luc right, I meant it that way. Atleast in concerns of dictionary attacks, however it does increase the amount of iterations needed, therefore slows the attack down, and avoids the use of precomputed rainbow tables. –  Mar 27 '19 at 11:22

3 Answers3

5

The use case of a "pepper" is to make it impossible to crack password hashes in the case the attacker has obtained the password hashes but not the pepper value. One such scenario would be limited SQL injection, where the database contents can be read but not the file contents.

One way to provide similar security would be to use asymmetric encryption. The client encrypts his password hash with the public key of the server. The server has the corresponding private key and can decrypt the password hash to verify it. This way, the client can perform the work to make the password hash available only to the server.

Sjoerd
  • 28,707
  • 12
  • 74
  • 102
2

There isn't any reason to use salts client-side. Using a salt server-side serves three purposes.

  1. It makes it so offline cracking effort spent recovering Alice's password isn't useful for recovering Bob's password. (As long as Alice and Bob have different salts.)
  2. It prevents offline cracking techniques that utilize precomputed hashes. (As long as salts are unpredictable.)
  3. It prevents someone with a dump of a password-hash database from determining whether two or more accounts use the same password. (As long as salts are unique.)

The client never receives a hash of a user's password. Checking the input against the stored hash is the server's job. If you gave a client a password hash then you are enabling offline cracking.

Salts are a way to make (offline) cracking as many password hashes as possible less easy. They are a layer of defense*, but they don't eliminate the danger of a password hash getting leaked.

(Leaked hashes allow offline cracking, meaning the server cannot impose rate limits or account lockouts. A server can't protect a user from their password getting cracked. Nor will it be able to tell when or if login credentials have been compromised.)

You're handing passwords wrong if you need to add a salt client-side. Only stored password hashes need to have salts. The exposure of password hashes should be as limited as possible.

* Salting does not protect individual accounts from being targeted. It also doesn't help if a cracker needs to compromise only one account; they can target everyone, guessing weak passwords, and successfully hack the account with the weakest password.


As you described it, the "pepper" is just a second salt. It's the same for all users and, if you give it to clients, it's not unpredictable. It adds nothing if it is not secret, so it should not be sent to clients.

Again, if you don't have the password hash then adding "pepper" to input doesn't serve any purpose.


One of the alternate definitions of "pepper" simply refers to encrypting password hashes and salts. This would provide total protection against offline cracking, assuming that encryption is done properly and that the key used isn't leaked along with all the password hashes.

This type of pepper is a good idea, but it's not perfect. It really only helps prevent offline cracking if just a copy of the password hashes get leaked. (For example, through SQL injection or, if the key is not stored on the same drive, someone copying the hash database from the server's hard drive.) It doesn't protect against total compromise of the server.


Use HTTPS. Clients (browsers) already implement it. It's easier than implementing your own encryption and you want use HTTPS anyways.

No matter what kind of password handling you do client-side, your user sessions will be vulnerable in some other way if communications are not encrypted and authenticated. (Session cookie stealing and man-in-the-middle attacks, for example.)

Plus if the JavaScript being sent to the client or the page that loads the script is not authenticated, then it's possible that the scripts or page can be tampered with in such a way that it defeats whatever client side hashing you do.

Future Security
  • 1,701
  • 6
  • 13
  • 1
    Client side salts aren't _entirely_ pointless, they prevent a shared precomputation attack if someone ever obtains client-hashed passwords before they're hashed by the server. Probably not a threat OP needs to worry about though. – AndrolGenhald Mar 26 '19 at 20:48
  • I also disagree about the salt part. If the connection *or* server is compromised, but the attacker does not want to reveal its compromise and therefore doesn't modify the login page, then salting client-side has all of the advantages that server-side salting has. Or if a sysadmin wants to have a peek, it would be harder to crack if he cannot modify the page to reduce the hash quality because a colleague or client might notice. Capturing on the server might be as simple as running Wireshark, leaving no trace. Since there is no downside to salting client-side, I would not call it pointless. – Luc Mar 27 '19 at 12:14
0

The other answers have covered how hashing salting and using a pepper make it difficult to crack passwords. As far as security of user credentials in transit is concerned, HTTPS Everywhere should take care of that.

Let us say an attacker is able to compromise the HTTPS connection and see the application traffic between the web browser and your server. Assuming this is your attack scenario, even if you add another layer of security (client side hashing/encryption), it is relatively easier for an attacker to alter the web pages served to the client's browser and obtain user passwords via phishing, rather than attempting to reverse engineer your client side security mechanism.

Shurmajee
  • 7,285
  • 5
  • 27
  • 59
  • "*an attacker [could] alter the web pages served to the client*" Except that this potentially gives away their presence. The NSA would probably not do this untargeted because someone might notice. An attacker that is hoping to use this backdoor for years might not do this either. If client-side hashing were widespread, people might even develop browser extensions that check for it, adding quite a lot of security because that makes it verifiable by ever single user. In the current situation, we usually need to just trust websites to do it on the server side... – Luc Mar 27 '19 at 12:19
  • I completely agree with the point that even a successful phishing attack may get detected sooner or later. Not sure how much of a benefit regular users would have by having verifiable form of security. I would personally never trust an add-on to check my web passwords. – Shurmajee Mar 27 '19 at 14:08
  • I think you misunderstood: the add-on would check that the form is unaltered, not some property of your passwords. It might also be a browser feature, etc. I'm just saying that if this were commonplace, it would be a great leap in transparency regarding password handling, which we could use to our advantage to make it even more secure. – Luc Mar 27 '19 at 14:19
  • A browser feature. Yes. Fair point. – Shurmajee Mar 27 '19 at 14:30