Best practices for handling PHP logins (session/cookie)

I’ve been searching for good, solid examples for secure login scripts using sessions, cookies, and some sort of password hashing.

Most of what I’ve seen so far is either extremely simplified and obviously insecure, quite “hacky”, or simply a soupy mess of code.

Are there any good “best practice” examples kicking around that I could reference?

Thanks :slight_smile:

Like this?

It’s too simplified and not entirely secure (compared to what’s in use now instead of 2003, anyway)

Force Flow:
Just store the logged in user id in a session.

On login: put in session.

On restricted page refresh, load it up from the db or cache.

On logout, kill the session.

For “security”, it’s the same for every site:

  • if you move the session id (SID) from one client to the other, you basically become that user. (Login in IE, copy the SID, paste it in FF, and you will be logged in without a user name and pass)
  • you can’t use cookies to store login info, since they are stored on the client pc
  • if you want to be a bit more secure, you make sure all passwords are posted to HTTPS servers (so never to HTTP).
  • to store the password in the database, you probably want to MD5 it or something, but that can be decrypted. You can use some sha function like sha1, if you want to be a bit more secure (or some ‘retarded’ way of storing either SHA either MD5 either whatever in there, to confuse the living hell off the guy that tries to hack your small site).
  • read up on PHP escaping user input and so on, and you will be all good.

md5 and sha1 are both a bit weaker. Use a stronger versions, like sha256.

Also, always salt passwords before hashing them, to prevent rainbow table attacks.

One more thing for extra security: change session id after the successful login.
as soon as you authenticated the username and password, just add this code:

session_regenerate_id();

Then continue with your other code.

Forgot one more thing: you can incorporate a failed loging attempts log. For example, record all failed login attempts into database table, then before every login check the records in that table to see if user already attempted to login and failed n number of times in the past x minutes.
If it’s true, then make the user wait for like 15 minutes or so before he can try again.
This will help prevent dictionary attacks where a hacker knows the username and just guessing passwords.

This is an extra effort on your part but can make your login system alot more secure.

How exactly to you prepare a password for sending from the HTML page in a visitor’s browser to the PHP page on your server?

If you hash the password in javascript, anyone can see what you used. If you use a salt, anyone can see what the salt is. If you use a combination of both, anyone can see what method you use. I doubt the password is usually sent in plaintext.

Not to mention, what do you do when javascript is disabled?

You have to use SSL.

If you do not want to use SSL, then you can try hashing with a salt. That will make replay attacks harder, but that’s about it. It’s a “better than nothing” approach.

And if JavaScript is disabled, then the user is completely protection-free!

Most sites send passwords in plain text. First, many people can not justify paying for the SSL certificate and second, SSL is also computationally intensive. This is why even big companies like Google make SSL (beyond login) opt-in.