7

I've been working on a full stack project recently for my own amusement and would like to add authentication services to this project, but want to make sure I'm doing it the right way. And before anyone says it, yes, I know: a well-tested and trusted authentication framework is highly suggested as it's likely you won't get your homegrown authentication just right. I'm well aware of this; this project is purely for amusement as I said, and I won't be using it in a production environment (albeit I want to develop it as though it will be used in a production environment).

I believe I have a fairly adequate understanding of the basic security principles in the authentication realm such as the difference between authentication and authorization, how you should never store plaintext passwords, why you should salt your passwords, why you should always prefer to use TLS/SSL connection between the client and server, etc. My question is this:

Should passwords be:

a) hashed and salted once server-side,

b) hashed and salted once client-side and once server-side, or

c) encrypted client-side and decrypted and then hashed and salted once server-side?

Many different variations of this question have been asked before on StackExchange (such as this question which links to many other good questions/answers), but I couldn't find one question that addresses all three of these options.

I'll summarize what I've been able to glean from the various questions/answers here:

  1. Passwords should not only be hashed on the client-side, as this effectively allows any attackers who gain access to the hash to impersonate users by submitting the hash back to the server. It would effectively be the same as simply storing the plaintext password; the only benefit is that the attacker wouldn't be able to determine what the password actually is, meaning that they wouldn't be able to compromise the victim's accounts on other services (assuming salting is being used).
  2. Technically speaking, if using TLS/SSL, passwords are encrypted client-side and decrypted server-side before being hashed and salted.
  3. Hashing and salting on the client-side presents the unique issue that the salt would somehow need to be provided to the client beforehand.

It's my understanding that the most widely used method is to hash and salt the password server side and to rely on TLS/SSL to protect the password in transit. The main question that remains unanswered to me is what if TLS/SSL is breached? Many companies, schools, and government agencies that provide network services on site have provisioning profiles or other systems in place to allow them to decrypt network traffic on their own network. Wouldn't this mean that these institutions could potentially view the plaintext version of passwords over their networks? How do you prevent this?

Razvan Socol
  • 167
  • 8
Jeffrey
  • 173
  • 4
  • 3
    It needs to be mentioned that hashing or pre-hashing client side might be possible (especially if you have fat clients or javascript) but the protection of that is limited, as the pre-hash becomes the Authenticator and can still be sniffed. It just" protects a bit against reversing the password, which might add minor protection to users who actually re-use passwords. Challenge/Response methods which don't need a shared secret (like SRP) would be an alternative. – eckes Jul 11 '20 at 13:09

2 Answers2

23

It's my understanding that the most widely used method is to hash and salt the password server side and to rely on TLS/SSL to protect the password in transit.

This is entirely correct.

The main question that remains unanswered to me is what if TLS/SSL is breached?

Then you are in a lot of trouble, and nothing else much matters.

In the context of the hostile network you're describing, reading your password is the least of your worries. They can see everything you see, and they can read everything you write. They can inject arbitrary content into any page you request in a browser. If TLS/SSL is breached by a MITM, nothing can save you, as the fundamental foundation of all other security is gone.

Trying to perform hashing on the client doesn't matter, if the MITM injects a keylogger that reads the password as you type it.

Many companies, schools, and government agencies that provide network services on site have provisioning profiles or other systems in place to allow them to decrypt network traffic on their own network.

They cannot decrypt traffic simply by virtue of it passing through their network. Typically they install a root certificate they own, and then MITM your TLS traffic and replace the certificate of the site you're trying to reach with their own certificate. When you try to establish a secure connection with example.com, you're actually establishing a connection with the MITM, using their cert, then the MITM establishes their own secure connection on your behalf to example.com. When you send something to example.com, you're actually sending it to the MITM, who decrypts it and then forwards it over their own secure channel to example.com.

Wouldn't this mean that these institutions could potentially view the plaintext version of passwords over their networks? How do you prevent this?

Again, only if you install their root certificate, and then intercepting passwords should be he least of your worries. You should never log in to any personal accounts on these devices, as you have no privacy, and as you say, all of your traffic can be read by the business.

user229044
  • 471
  • 3
  • 8
  • 2
    Thank you—it was the understanding of how an institution uses a root certificate to be able to intercept and decrypt the TLS traffic that was missing. It makes much more sense now! – Jeffrey Jul 11 '20 at 02:04
  • (ps, client-sided password hashing would still protect the password against a purely passive logging MITM) – user1067003 Jul 11 '20 at 23:58
5

As you have seen, the general consensus is that you need to salt and hash server side, and send everything over TLS. While you can do hashing or encryption on the client side, it does not protect against the threats you are concerned about.

Many companies, schools, and government agencies that provide network services on site have provisioning profiles or other systems in place to allow them to decrypt network traffic on their own network.

Assuming you mean that the user has installed and trusted the root CA, yes. TLS isn't decrypted, but terminated by the proxy.

... these institutions could potentially view the plaintext version of passwords over their networks? How do you prevent this?

Imagine you are using the most secure cryptography to encrypt the password on the client side before it is sent to the server. However, you cannot forget that a TLS intercepting proxy can do far more than just view contents of TLS traffic; it can also modify things. To defeat your strong crypto, all the proxy has to do is inject a basic JavaScript keylogger into every page that will steal the password as it is being typed. Or in a corporate setting, the computer could be logging keystrokes already.

So, it's fairly safe to say that securing web browser traffic from a TLS proxy is pretty futile.

So what's the solution? At least for myself, I would never enter a password into a site if I know the traffic is being intercepted. Further, I do not log into sites on computers I do not own and trust.

From a design perspective, if it is absolutely unacceptable that a password is ever visible to a TLS proxy, you could instead create a native application that enforces certificate pinning and/or communicates with the server using asymmetric keys hardcoded into the app.

multithr3at3d
  • 12,529
  • 3
  • 31
  • 43