3

So I am trying to implement a client-server application for sending files over SSL sockets. And I am trying to decide on a very secure design for authenticating the client.

The server is going to have access to a database holding all the usernames and hashes for their passwords (so if the DB gets hacked the passwords are going to be "safe").

I am wondering if sending the password as a plain text that is then hashed at the server and compared with the hash on the database is the most secure option or not.

It sounds a bit insecure sending the clients password without any randomness in it but I don't see how else it could be implemented.

Any pointers would be much appreciated!

4

Passing the Hash If you hash the password on the client, you run the risk of introducing a pass-the-hash (PTH) flaw. This is a real, surprisingly common phenomenon that significantly impacts the security of your application. It has been a key security issue in Windows for years: https://en.m.wikipedia.org/wiki/Pass_the_hash

(EDIT: the Windows example above talks about weaknesses in the NTLM challenge-response protocol. A well-designed challenge-response protocol should not be vulnerable to PTH, although these protocols have largely been superseded by transport layer security. See below.)

Essentially, if you hash the password first, the value that you are using to authenticate against the server is actually a hash of that password, and not the password itself. Therefore, an attacker only technically needs to know the hash, and not the password itself. As a result, if the database were compromised, you're now foobarred, because the attacker has all of the credentials they need.

Workaround You could work around this by hashing on the client, and hashing that hash again on the server. This means that the database would contain a list of hashes that still need to be cracked before they are useful.

However, this doesn't particularly help your transport security dilemma. Whatever value you send to the server during authentication (the password or just a hash) is the value that an attacker can use to authenticate with against the server. Therefore, a client-side hash always has the same risk profile as the password itself. You're no safer by transferring it as a hash.

TLS As a result, you're best focusing your attention on a good TLS configuration. Make sure that the client will never send sensitive information over a cleartext protocol, and that it only accepts valid server certificates. Consider certificate pinning if available. Configure support for only the most secure protocols and cipher suites on both the server and client.

Alternate authentication methods (all of which have the potential to be invulnerable to pass-the-hash if implemented correctly):

Such protocols are largely unnecessary in modern applications due to the increased availability and interoperability of TLS.

  • +1 "an attacker only technically needs to know the hash, and not the password itself" – elsadek Oct 11 '15 at 12:12
  • thanks for the reply. I am indeed using the SSL socket to send the username and password over to the server. And with my current implementation the client includes the server certificate in its truststore. Should I implement the server trusting the client's certificate as well as a part of a "good configuration"?? – Rakim Oct 11 '15 at 12:43
  • In addition, on the link you provided it is mentioned that: "The attack exploits an implementation weakness in the authentication protocol in that the password hashes are not salted, and therefore remain static from session to session until the password is next changed". Can you please explain that. Because this sound to me the same as the "randomness" on every session I was talking about on my initial question. How do I salt the password hashes in my scenario and what does it protect me from? Thanks – Rakim Oct 11 '15 at 12:49
  • @Rakim I've updated my answer to clarify a couple of things. Regarding your additional questions: 1) A client-side certificate is for use in specific circumstances, as opposed to just being 'good configuration'. You could issue clients with certificates to verify the machine that is connecting, or to verify specific users (a second factor of authentication). 2) NTLM is a challenge response protocol. If you implement a challenge response protocol for authentication, then you'll be interested in salting for transport. If you just use TLS, you would only be concerned about salting for storage. – itscooper Oct 11 '15 at 13:35
  • Salting for storage: security.stackexchange.com/questions/51959/… – itscooper Oct 11 '15 at 13:37
0

When you are already using SSL, there is no reason not to also use SSL for getting the user's password. This will, of course, require that you either have a certificate from a trusted certificate authority or that the client trusts your certificate. When you are talking about a stand-alone executable your users install, you can include your server's certificate in it.

  • the client is indeed trusting the servers certificate with the current implementation. Is that sufficient? – Rakim Oct 11 '15 at 12:44

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.