2

I want to authenticate my users based entirely on cookies and sql db.

What I do is:

1. Once they login, I generate a random string, create a hash from it, save it in the database along with the user id and his IP.

2. I send the hash to the user as cookie

3. Whenever he wants to access something, I verify if his cookie hash matches the one on the server and also if his IP matches. Of yes, he is valid or else, log him out.

4. (As pointed by Akhil) If he clears his browser cookies or anything does not match the information on the database, I clear all the rows with his username and log him out.

Note: I use a session cookie for storing the random hash, which again is generated using the timestamp, and as long as time doesn't repeat itself(I believe), its random in the corect way.

Is this fine? How can I make it better?

xprilion
  • 569
  • 1
  • 5
  • 14
  • I'd recommend not to reinvent the wheel. Unless you're trying to improve existing methods you shpuld probably not implement this yourself. – Dennis Traub Mar 02 '14 at 10:33
  • what happen if any clears the cookie or if the cookie expires ? how will he be able to login ? you can never relay on ip address. How are you coing to deal with dynamic ip address ? i think keeping password will be a simpler method – Akhil Sidharth Mar 02 '14 at 10:35
  • "generated using the timestamp" doesn't seem random. Hashing the random string seems like an extra, unnecessary step, if your string is truly random. – Marcus Adams Mar 03 '14 at 15:51
  • I mean..I take the timestamp, and hash it..simple..is that not random? :o – xprilion Mar 03 '14 at 17:44
  • Need any more help? If so I'll update my answer. – SilverlightFox Jul 29 '14 at 09:48

3 Answers3

2

Your method only makes sure that the user possess the random string you generated and is using the same external IP address. There exists several way of abusing this system:

  • if your website doesn't enforce HTTPS then a user connecting using an unsecured public WiFi network could be at risk: if another user of the WiFi network is listening to all the packets being sent on the network, he could intercept your cookie and use it to access the website as your legitimate user. Your server would be unable to differentiate them because they'll both use the same IP address... (There is a Firefox extension available which enable anyone to intercept such login cookie easily: http://en.wikipedia.org/wiki/Firesheep)

  • This system is also more generally vulnerable to man in the middle attacks (without HTTPS)

  • If your cookie is stored on the user computer's hard drive it could be reused by another user.

So to answer your question, your system can be deemed as secured provided a few conditions:

  • you enforce the use of HTTPS on your website (unencrypted HTTP connections should be refused)

  • your random string is truly random (there exist right and wrong ways of generating random strings in PHP)

  • your cookie has a short expiry and preferably is set as a session cookie.

You should take a look at the following related question providing details about the proper way of doing what you want to do: How to secure an authentication cookie without SSL

Community
  • 1
  • 1
2072
  • 275
  • 3
  • 6
2
  1. Once they login, I generate a random string

Make sure you use a cryptographically secure method to generate the random string. Do not use mt_rand use something such as openssl_random_pseudo_bytes.

create a hash from it,

Make sure to use a secure hashing algorithm (not MD5, and at least SHA-2).

save it in the database along with the user id and his IP.

One thing to bear in mind is that some internet connections share IP addresses or will sometimes change the client IP address (e.g. AOL or mobile).

  1. I send the hash to the user as cookie 3. Whenever he wants to access something, I verify if his cookie hash matches the one on the server and also if his IP matches. Of yes, he is valid or else, log him out.

It sounds like a good way of doing it and there are no flaws in itself. I would implement a session timeout mechanism. For example, store the date last used in the DB for a sliding expiration and the query will only query records that have not expired. You could have a background process that runs to clear out old, expired records.

Also, use HTTPS and set the Secure and HttpOnly flags on the cookie. This will prevent them being leaked over HTTP, but I would not go as far as disabling HTTP on your system as there are workarounds for an attacker if it is anyway.

I would not be concerned with the cookie being stolen by another user on the same machine. If the cookie can be stolen in this way then the user's machine is probably compromised anyway and you cannot make your system protect data that is outside of your control. You could however renew the token (random string) on a periodic basis giving the user a rolling cookie. You would have to ensure only one user can be logged in at once under the same account though for this to be effective.

Marcus Adams
  • 53,009
  • 9
  • 91
  • 143
SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
0

One cannot say this is "bad". But in Web Development, and specifically in its security domain relativity talks. I recommend you to download a CodeIgniter (google it for more info) Session Class (standalone version) and use it. The basic idea is the same as yours, but it is properly more mature since it is developed in such a famous php framework. You can do your DB operations within that class too, since it allows session saving to DB.

Mostafa Talebi
  • 8,825
  • 16
  • 61
  • 105