6

I am currently developping a platform with a PHP framework for our client.

The head of the client's IT department wants us to handle authentication with one database field containing email+password+salt (hashed) so there isn't a plain text email field in this table and the password is more secure (his reasoning). The user should be able to login with his email address and password. So the email address serves as the username. The idea behind this is that the email addresses of the users are very important for the business of our client and the IT head wants to obscure the email address in the login table in case of a possible attack. (e.g. a hacker gets access to the login table)

This is of course only possbile, because the hashed email adress for the login is linked to his email address in the profile table. Basically there are two tables which are required for this process to work. The tables are in the same database of course. One login table with the hash combination field (email, pw, salt) and one profile table which contains among other things the email in plaintext in one field. Let's call it profile_email.

I have strongly recommended not to use this solution, because I have never before heard of this and I have already identified some possible problems with this solution.

So my questions are: Is this a safe and feasible solution? Can you think of any unforeseeable problems? Have you heard of similar solutions?

  • 2
    I agree with @Xander answer, this suggested implementation/design is useless. The question is how the attacker will get access to the login table only. If your data base compromised/hacked, it is end of the story. I believe the login request goes to the profile_email table first and then to the login table to compare the hashed credential right? In this case a SQL injection will most likely target the profile_email table. Last point is encryption/hashing is to protect sensitive/private data. As far as I know email addresses are meant to be public! – Ubaidah Oct 12 '14 at 2:59
  • 1
    That was also my first question to the IT Head, but I didn't get a straight answer. The Login request only goes through the login table because it only needs to check the one single database field (email+password+salt), but in every other instance (passwort reset, ...) the profile_email field needs to be accessed. So this combination field is basically used for both identification and authentification. – SEoCid86 Oct 12 '14 at 3:24
  • 1
    Sounds like a XY problem. See if you can agree to the underlying requirement instead of the implementation details. Also see the Perl monk's thoughts about this subject – agtoever Oct 12 '14 at 5:48
  • 3
    @SEoCid86 if the login request goes to the login table directly, then it is possible you could be vulnerable to DOS attack. If the way you authenticate the user by hashing the email+password and look up the hash value in the login table then you most likely vulnerable to DOS attack. If there this no restriction on the email length then I could send a login request where the email is 1000 characters and your server will hash the 1000 chars email and the password which is an expensive process. Now if I flood your server by thousands of this malicious login. You server will expire a DOS attack – Ubaidah Oct 12 '14 at 6:27
  • 1
    @agtoever: I'm aware that it isn't a straight forward question which asks for a specific solution. The Problem is, as I explained, not finding a solution but trying to determine, if the security of the system is compromised by the solution the clients IT head has proposed. – SEoCid86 Oct 12 '14 at 6:34
12

As far as I can tell, this scheme doesn't make any sense. As you've noted, you still need to store the plaintext email address for the user, so there isn't any significant security benefit to using the plaintext email and email + password + salt hash vs just using plaintext email and password + salt hash.

As I'm sure you've already noted, without the plaintext email (regardless of whether it's in the profile table or the login table) relying solely on a single hashed value of email + password + salt is infeasible (you would have to go through each row, getting the salt, computing the hash, seeing if it matched, if no match, getting the salt from the next row, computing the hash, seeing if it matched, etc, etc, etc...) and would be a security disaster, because it would allow an attacker to test the hashes for all users on the site with a single login attempt vs. only being able to test the hash for a specific user.

I don't see any good reason to do this. It doesn't improve security, it does increase complexity, and the implementation is fraught with peril. You should politely, but firmly push back on the client to follow standard best practices rather than trying to invent his own harebrained scheme.

  • Thank you for your answer! One Thing I'm also worried about is that storing authentification/identification values across multiple tables will make some additional measures to secure the sensitive content in the profile table difficult or in some instances maybe even impossible (Can you think of any?) On top of that, wouldn't increasing the number of instances the profile table needs to be accessed make this part of the database more vulnerable? – SEoCid86 Oct 12 '14 at 2:20
5

Could there be some miscommunication between you and the IT department head? As Xander had already pointed out, such a scheme does not work, and I would even add that it is ridiculous. In order to authenticate a user, a database lookup has to be performed on the login email address in order to retrieve the corresponding hash used for comparison:

SELECT hash from Users WHERE email=?;
if($hash == hash_func($password)) then Grant access

What you are proposing now is to make the lookup more complicated by adding a JOIN operation to avoid a direct lookup on the Users table:

SELECT U.hash from Users U INNER JOIN Profile P WHERE P.id = U.id AND P.email=?;

Querying two tables residing on the same database does not improve security at all. It will also make the authentication process more cumbersome and computationally expensive.

If the email addresses need to be protected, then it cannot be used as part of your authentication scheme. A typical way to overcome this problem is to use a username in conjunction with the password. This will remove the need for doing a lookup based on email address:

SELECT hash from Users WHERE username=?;

Then it will also allow you to encrypt the email addresses to protect them. If your database is hosted on a different server from your application, anyone who manages to access the database may not be able to retrieve the email addresses.


Thanks for clarification. The above answer is in response to your proposal as stated in the third paragraph of your question. As I understand from your comment below, your client suggested a radically different approach which does not require the usage of a second (profile) table:

SELECT id from Users WHERE hash=?;

The above scheme is only workable if you ensure that all hashes in the table is UNIQUE. Since no lookup of the login email is being done, you need to address the following security concerns:

  • how to prevent brute-forcing on an individual account
  • likelihood of matching a hash as database gets large
  • ability of your site to handle DDOS attack on login page since hashing is always performed

By the way, does your client accept the risk of a user entering the wrong password and logging in as another user? If yes, then you can proceed with this.

  • The Idea was that the Ident/Authentification will happen simultaniously. It will combine the email and password entered by the user with the salt, hash it and then start to search for this hash in the login_table. I also thought that a Username solution could be the answer, but this would violate other project requirements, that are more important to the client. – SEoCid86 Oct 12 '14 at 4:45
  • @SEoCid86, please see my update. – Question Overflow Oct 12 '14 at 5:55
  • Wouldn't the Hash be unique, if the email adress is unique (part of the hash)? – SEoCid86 Oct 12 '14 at 6:19
  • @SEoCid86, even if the hash is unique in the table, there is still a small possibility that hash(email1.pass1) = hash(email2.pass2), where pass2 is the wrong password for email2 which produces a matching hash. This is known as a hash collision. This possibility increases with the size of your database. – Question Overflow Oct 12 '14 at 6:49
  • Thank you for bringing this to my attention. I didn't know that such a collision was possible. – SEoCid86 Oct 12 '14 at 6:56

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.