Password Security:Key Pair Exchange

yehster wrote on Monday, April 08, 2013:

In thinking about the security vulnerabilities with the current password mechanism, I’ve come up with what I think is a better idea than doing both a client side hash (javascript based) and a server side hash that we’ve been talking about before.

The approach I think would work better is for the server to generate a public/private key pair for use during only the current session and present the public key to the browser on the login screen.

Then the browser can use that public key to encrypt the password for transmission to the server. The server would then decrypt the password, hash it and then use the hash for authentication.

This way, even if intercepted in transit, the authentication info can’t be as easily used to impersonate a user since it will use a different key pair for each session, as opposed to a hashed password which wouldn’t change.

The login mechanism will use what’s basically the equivalent of SSL for submitting the username/password even if the server isn’t properly configured.

bradymiller wrote on Tuesday, April 09, 2013:

Hi Kevin,
That sounds good if can get it to work; then can avoid multiple hashing and can hash on the server end of things.
-brady
OpenEMR

yehster wrote on Tuesday, April 09, 2013:

The tricky piece here is managing the public and private keys. It’s not possible to use $_SESSION to store the private key because the login.php page immediately expires the session cookie so I am going to come up with an alternate mechanism.

However, the alternate mechanism will also have an advantage in that I can make it “one time use.” So if the encrypted password is intercepted in transit, an eavesdropper won’t be able to use it.

Anyway, I’m really just “thinking aloud” here. It will all make more sense once the code is ready.

yehster wrote on Wednesday, April 10, 2013:

Spamming to see if I get this update via email notification now.

ariesbeck wrote on Wednesday, April 10, 2013:

I have a couple of ideas to help you going forward. I look forward to some patches coming out soon. I wanted to point out some flaws with auth.inc and another forum member pointed me here, indicating you were already working on some of them(http://sourceforge.net/p/openemr/discussion/202506/thread/7ba71fad/). Here are my concerns and some proposed solutions:

1.) SQL Injection. The auth.inc file is full of sql injection vulnerabilities. Most of the SQL queries dont make use of the sqlStatement functions second parameter which allows you to write a query like this: sqlStatement(“update sometable set blahcolumn = ‘?’ where id = ?”,array($somestring,$someinteger)) right now a user could very simply inject sql into the login process.

Solution:
Update the queries in auth.inc to use the second parameter of sqlStatement properly.

2.) Terrible hashing strategy(as you pointed out). Client side hashing is nice, but unnecessary if SSL is used as every transmission will already be unique. It is also completely useless in the way it has been implemented. It provides no security whatsoever, encrypting on the client side makes the transmission yet again vulnerable since the encrypted password is transmitted and is all that is required to gain access. If an attacker was to get ahold of the “hashed” password stored in the database of another user they immediately have access to their account. In a properly implemented hashing scheme the hash is performed server side and prevents an attacker from ever having the ability to use even a stolen users table to gain access to a system. Salting is also extremely important as plain MD5 without a salt is a losing battle, huge databases of MD5 hashes exist which would allow an attacker to convert a hashed MD5 password back into clear text(the one benefit password hashing is supposed to provide is preventing decryption).

Solution:
Update the hashing strategy and move it to the server side. It should include at the minimum a per-user salt. During enrollment or password changing the system would generate a random salt for the user and store it in the database. That salt would then be used when hashing the users password for comparison. Check out http://crackstation.net/hashing-security.htm for further explanation.

Secondary Solution: Warn downloaders that SSL should always be used, possibly enforce it somehow, it is incredibly unsafe otherwise.

I hope this isn’t to overwhelming to throw at you. I would advise you to switch gears and stop thinking about how to protect non-SSL users and dump client side encryption, they are doomed anyways and they should realize that EVERY transmission after login will be transmitted insecurely…that means all patient data, etc…

If you want any help please feel free to let me know!

Aaron

yehster wrote on Wednesday, April 10, 2013:

The most helpful thing will be additional people reviewing the new code when it’s ready.

bradymiller wrote on Thursday, April 11, 2013:

Hi Kevin,
Just let us know when it’s ready to look at. Looking very forward to seeing what you come up with; from your discussion above, it looks like OpenEMR’s hashing/password mechanism may be jumping from the 1960’s to the 2100’s :slight_smile:
-brady
OpenEMR