views:

159

answers:

6
+4  Q: 

PHP Login System

I am creating a login system for a web application using PHP. My question is, is it safe to only store the user login information in the current session? For example, if a user named John logs in successfully to my site, can I just store $_SESSION['Username'] = 'John' and $_SESSION['LoggedIn'] = 1 then check that $_SESSION['LoggedIn'] is equal to 1 on each page to verify the user is actually logged in? Or is there a better way to do this? I am not aware of any problems this may cause off the top of my head, but I wanted to make sure I wasn't leaving a big hole in my site that would cause problems down the road.

Also, I am storing an md5 hash of the user's password + salt in the database, not their actual string password so that is one less thing to worry about.

Let me know if you need any more information or if this is not clear. Thanks!

+5  A: 

That's a perfectly reasonable approach. Your visitors will never be able to edit the session data on your server (unless the server itself is insecure, in which case anything's fair game), so a LoggedIn=1 value in the session is perfectly safe.

However, do keep in mind the risk that one visitor hijacks the session of another (by stealing the session key). One way to help protect against this is to also store the visitor's IP address (from $_SERVER['REMOTE_ADDR']) in the session and then in later requests confirm that it hasn't changed.

VoteyDisciple
This can problematic as traffic from the NAT gateways of some ISPs comes from a number of IP addresses, round-robin-style.
staticsan
That number is quite small in practice (and represents a poorly-designed ISP, to boot).
Jed Smith
A: 

Sounds OK; you may want to think about setting an expiry time (so if someone walks away and leaves the browser open they're not in too much danger).

Artelius
+1  A: 

Consider SHA1 or an even stronger hash instead of MD5. You're salting it, though, that's good.

Back to your question: yes, that's fine. However, implement measures to make sure sessions are not hijacked. Wikipedia actually has a fairly good article on it.

In most of the systems I've written, I've included logic to verify the remote IP hasn't changed. You can store that in the session, too, since the session vars don't get passed to the user (only the session ID). If you really want to get creative, you can add other checks -- user-agent, and what not.

You also have to account for session attacks. Check referrers. If you have a disastrous operation, let's call it a POST to DeleteMyAccount, I can write a form submission plus javascript to hit DeleteMyAccount in a forum post on an unrelated site, counting on that session to be present in the user's information.

Jed Smith
+1  A: 

There are a number of risks to consider:

  1. Session hijacking: this is where someone steals the user's cookie and pretends to be them. Some will suggest IP filtering to counter this but that can have awkward side effects. People use Websites from mobile devices or on laptops that are used at work, home and at wifi hotspots and there are other cases where IP addresses can change. So my advice is only do this for highly sensitive Websites (eg online banking);
  2. Your Site is Compromised: in this case the user will have access to your database anyway so there is no extra risk with storing authentication information in the session. They can just as easily change who they are by issuing UPDATE statements to your database;
  3. A Co-Hosted Site is Compromised: if you use shared hosting, a completely unrelated site could put you at risk (with or without this scheme) because a bunch of sites are all running on the same Apache instance and can thus access each other's files (although it can be hard to figure out what site they belong to). So if a site you've never heard of is hacked it can impact your site;
  4. A Co-Hosted Site is Malicious: similar to (3) except the threat is internal but is otherwise similar.

So I'd say it's fine (subject to (2)) but just be aware of the risks. Follow, at a minimum, these best practices:

  1. Never store unencrypted passwords;
  2. Use a strong hashing algorithm (SHA1 preferred or MD5 at least);
  3. Make sure authentication cookies expire at some point. How long depends on your site. It could be a week or two or an hour or two of inactivity or both.
cletus
A: 

On the whole, you are definitely on the right track. I would recommend you use IDs for your users in the session rather than the username as IDs are a better unique reference inside your code.

Also, md5 is not considered strong enough for password hashing anymore: it's is too fast to hash and you don't want that in a check that an attacker will need to run over and over again (whilst a real user only needs to do it once). I wish I could find the reference, but leading edge wisdom is to do lots of rounds of a leading edge hashing algorithm, like sha512.

staticsan
A: 

You can use COOKIE instead of SESSION variable. you may set COOKIE by following

setcookie('ID', $variable, time()+8*60*60);

You have to be aware about SQL Injection. When you Insert or Update your database where user textbox relates please be aware about SQL Injection. Insert / Update your values by htmlentities() function.

Tareq
You are apparently commenting to the post by staticsan - this should be done in a comment instead of an answer, since the order of answers is *not* static. Interpreted as a reply to the actual question *"Is it safe to only store the user login information in the current session?"* your answer *"You can use COOKIE instead of SESSION variable."* suddenly looks very wrong and dangerous.
Ilari Kajaste