PHP question (stay logged in)

Areeda

Pattern Altitude
Joined
Aug 21, 2005
Messages
2,188
Location
Los Angeles, CA
Display Name
Areeda
Home Airfield
KEMT - El Monte, CA
I've been writing my php sites to stay logged in to the end of the session. Now I have a need to keep users logged in for a year.

Googling for ways to do this has not been very fruitful, so I thought I'd ask here while I continue my research.

I'm thinking of a cookie that hashes say ip, and user name. A table that stores these and when a new session is created if the cookie exists remotely and in the table just log them in.

What do you do?

Joe
 
What you proposed sounds like a workable solution. Does your solution have to work even if cookies are disabled?
 
Can't you just set the cookie expiration date for a year?

setcookie("Userhash", $value, time()+(60*60*24*365));
 
I also found this:

You can set the session lifetime with ini_set():

ini_set('session.cookie_lifetime',(3600*24*365)); // makes cookie good for a year

One problem with that is the server's temp directory might get clogged with saved sessions. If you have a high traffic site, this could cause problems. You can either use cookies, or make the cookie lifetime something like 30 days.

See http://www.php.net/ini_set for more information.
 
What you proposed sounds like a workable solution. Does your solution have to work even if cookies are disabled?
I don't think so. If they don't want cookies they have to log in each time, I'm just trying to help people using smart phones with crappy keyboards.

Can't you just set the cookie expiration date for a year?

setcookie("Userhash", $value, time()+(60*60*24*365));
Mike,

That keeps the cookie for a year (although Adrian Monk would check if it's a leap year) but my problem is what to do with the cookie.

Joe
 
I don't think so. If they don't want cookies they have to log in each time, I'm just trying to help people using smart phones with crappy keyboards.

Mike,

That keeps the cookie for a year (although Adrian Monk would check if it's a leap year) but my problem is what to do with the cookie.

Joe

Not understanding you, Joe. The cookie is on the client; the session is on the server. What do you need to do with the cookie? Correlate the session with the cookie key? If so, look at that ini_set function--I haven't tried it, but it may do what you're looking for.
 
Last edited:
If I coded like Monk, I'd never get anything done :D

Not speaking to your specific security needs, but can it be as simple as:

if(login_successful)
setcookie("Userid", $userid, time()+(60*60*24*365));

then, next time they visit:

if($_COOKIE['Userid'])
{
$userid = $COOKIE['Userid'];
login_successful=1;
// do interesting "welcome back" type stuff
}

...?
 
Not understanding you, Joe. The cookie is on the client; the session is on the server. What do you need to do with the cookie? Correlate the session with the cookie key? If so, look at that ini_set function--I haven't tried it, but it may do what you're looking for.
Bingo!

If I coded like Monk, I'd never get anything done :D
Oooh, right through the heart!

Thanks guys, I really do appreciate the fact that I get better technical support here than any of the other websites I visit.

Joe
 
You wouldn't want to have the cookie be the user_id or any reasonable hash of the name, otherwise a smart user could log in as anyone if they wanted to.

What I usually do, is store a GUID in the cookie, which corresponds to a 'session' record in the DB. In your case, it would just be a 3 column table (GUID, expire date and user_id).

You would also set the expiration in the cookie if you wanted, but make sure to enforce it on the server.
 
Now the important question....


... whatcha workin on, Joe? ;)
 
I've been writing my php sites to stay logged in to the end of the session. Now I have a need to keep users logged in for a year.

Googling for ways to do this has not been very fruitful, so I thought I'd ask here while I continue my research.

I'm thinking of a cookie that hashes say ip, and user name. A table that stores these and when a new session is created if the cookie exists remotely and in the table just log them in.

What do you do?

Joe
Create a table with the user id and a random session id. When a user logs in pop a cookie onto their machine that contains that random session id. When you check to see if a user is logged in, check and see if they have that random session cookie -- if so -- start a new session.

There are some security concerns. A few "best practices":
- When the user manually clicks log out on the website -- delete their 'remember me' session row from the table above.
- Make sure to expire those cookies based on your time frame (1 year) *AND* the row in the database.
- Keep the cookie simple. Nothing but that random id. Make it REALLY random.

The above is basically how you have to do it. Most apps will do it this way -- including vBulletin.

Of course you'll want to wrap the above nicely into some sort of user / permissions utility.
 
Last edited:
Looks like everyone above covered it. If your user tries to do something sensitive and came in one of your "last nearly forever" cookies I would force them to type their password again.

For example, I'll generally have a user object with an isTrusted attribute. If they came in on a super-long-remember-me cookie I won't set that isTrusted. On certain aspects, like changing their password or their e-mail address, if they aren't "trusted" then I make them re-type their password. This might sound like paranoia but it is a good idea as those cookies can get jacked.
 
Looks like everyone above covered it. If your user tries to do something sensitive and came in one of your "last nearly forever" cookies I would force them to type their password again.

For example, I'll generally have a user object with an isTrusted attribute. If they came in on a super-long-remember-me cookie I won't set that isTrusted. On certain aspects, like changing their password or their e-mail address, if they aren't "trusted" then I make them re-type their password. This might sound like paranoia but it is a good idea as those cookies can get jacked.

Ah, I bet that's why Amazon.com and EBay will let me do most things on "remember me", but still require my password at least once in any specific session before doing certain transactions. Good security policy.
 
Definitely make sure the info in the cookie is from a hash. Anything that is user readable is asking to be hijacked. On top of that, I personally wouldn't rely solely on the cookie. You can set session variables for the user's browser while they're logged in, and if you find someone with a cookie but no session variable on their browser, you can ask for the password just to be doubleplus sure (thus setting the variable for that browser session). Otherwise all one would need to do is copy the cookie and they've got access. Overkill maybe, but that's just my .02
 
Looks like everyone above covered it. If your user tries to do something sensitive and came in one of your "last nearly forever" cookies I would force them to type their password again.

For example, I'll generally have a user object with an isTrusted attribute. If they came in on a super-long-remember-me cookie I won't set that isTrusted. On certain aspects, like changing their password or their e-mail address, if they aren't "trusted" then I make them re-type their password. This might sound like paranoia but it is a good idea as those cookies can get jacked.

Yeah, that. :D
 
Definitely make sure the info in the cookie is from a hash. Anything that is user readable is asking to be hijacked. On top of that, I personally wouldn't rely solely on the cookie. You can set session variables for the user's browser while they're logged in, and if you find someone with a cookie but no session variable on their browser, you can ask for the password just to be doubleplus sure (thus setting the variable for that browser session). Otherwise all one would need to do is copy the cookie and they've got access. Overkill maybe, but that's just my .02
That would defeat the purpose of what he is trying to do. He wants the user to stay logged in for a year. If you set a SESSION (session-only) cookie the browser will delete it when the browser is closed.
 
That would defeat the purpose of what he is trying to do. He wants the user to stay logged in for a year. If you set a SESSION (session-only) cookie the browser will delete it when the browser is closed.

Another option is to store some of the browser info (header variables) in your table along with the key/hash you generate. Some basic comparisons can help determine if the cookie is coming from a different (or new) browser. IP would be too specific, but you can poke around at what the browser sends you and try to find some things to help secure it.

You can go too far, too, trying to catch that .0001% of hackers. How likely is your app to be hacked, and is there anything of "value" to go after? That would help dictate to me how much effort I put into protecting it.
 
Another option is to store some of the browser info (header variables) in your table along with the key/hash you generate. Some basic comparisons can help determine if the cookie is coming from a different (or new) browser. IP would be too specific, but you can poke around at what the browser sends you and try to find some things to help secure it.

You can go too far, too, trying to catch that .0001% of hackers. How likely is your app to be hacked, and is there anything of "value" to go after? That would help dictate to me how much effort I put into protecting it.
You could try something like that -- but a smart hacker that was smart enough to jack the cookie will be smart enough to forge a few headers. You then end up breaking the remember me feature everytime a browser updates (which is many times during a year).

Web security leaves a bit to be desired. You just have to work with what you've got (cookies) and decide the risk you're willing to take to enhance the user's experience.
 
Last edited:
I made the assumption that any information gained by logging in was not super-critical, else a 1yr session would be excessive.

I also assumed he was aiming more for user convenience than informational security in this case. :D I also got the impression that he knew how to architect the app for his needs, he just was not sure of the particular methods for setting and getting cookies.

(shrug)
 
Definitely make sure the info in the cookie is from a hash. Anything that is user readable is asking to be hijacked. On top of that, I personally wouldn't rely solely on the cookie. You can set session variables for the user's browser while they're logged in, and if you find someone with a cookie but no session variable on their browser, you can ask for the password just to be doubleplus sure (thus setting the variable for that browser session). Otherwise all one would need to do is copy the cookie and they've got access. Overkill maybe, but that's just my .02

As Jesse mentioned, you want a random number. A hash, by definition, could be regenerated. This means that a smart user could find the cookie, and change the hash out with one he can make based on analyzing a previous cookie.
 
As Jesse mentioned, you want a random number. A hash, by definition, could be regenerated. This means that a smart user could find the cookie, and change the hash out with one he can make based on analyzing a previous cookie.

Bwa? I know people have been/are working on rainbow tables, but you're assuming that A) the hacker knows what you're using to compute your hash, B) what hash function you're using, and C) that it's easy to discern a valid value to compute a hash for a given user. Revealing any of those three is a big no-no... I hope you weren't thinking that I meant to use something like the username to generate the hash.
 
Bwa? I know people have been/are working on rainbow tables, but you're assuming that A) the hacker knows what you're using to compute your hash, B) what hash function you're using, and C) that it's easy to discern a valid value to compute a hash for a given user. Revealing any of those three is a big no-no... I hope you weren't thinking that I meant to use something like the username to generate the hash.

Security By Obscurity is no Security at all.

Rainbow tables are getting extremely good for the normal hash functions, however, discounting that:

1- You are assuming your source code will never be seen by someone you don't want seeing it. Everything from ex coworkers to a misconfigured web server can give access to the hashing algorithm/what you are using.
2- A hash implies you are using some bit of information about the user (username, user_id number, etc). In this case, an existing user can figure this bit out about themselves, and check the cookie, then decompose it with a limited bit of work.

A completely 'random' key is significantly more secure, since it results in the individual having to guess correctly from the entire keyspace.
 
You could try something like that -- but a smart hacker that was smart enough to jack the cookie will be smart enough to forge a few headers. You then end up breaking the remember me feature everytime a browser updates (which is many times during a year).

Web security leaves a bit to be desired. You just have to work with what you've got (cookies) and decide the risk you're willing to take to enhance the user's experience.

Yeah, but he'd have a tough time guessing which things I had peeled out of the original cookie user's header info... there's lots of user agent strings out there.
 
Yeah, but he'd have a tough time guessing which things I had peeled out of the original cookie user's header info... there's lots of user agent strings out there.

Chances are it could be guessed pretty accurately within 10-15 guesses, just try the most popular of each, and you'd be set.
 
Yeah, but he'd have a tough time guessing which things I had peeled out of the original cookie user's header info... there's lots of user agent strings out there.
If you jacked the original user's cookie -- it wouldn't be hard to jack the headers that come with his request either :) You'd just do both at the same time. Remember that a cookie is simply a header. Depending on how you stole the cookie it may just all be right there for you.
 
Last edited:
If you jacked the original user's cookie -- it wouldn't be hard to jack the headers that come with his request either :) You'd just do both at the same time.

And you'd know that was what I was doing in server-side code how? :rolleyes:

(OH YEAH, because I told you here... crap!)
 
Security By Obscurity is no Security at all.

Rainbow tables are getting extremely good for the normal hash functions, however, discounting that:

1- You are assuming your source code will never be seen by someone you don't want seeing it. Everything from ex coworkers to a misconfigured web server can give access to the hashing algorithm/what you are using.
2- A hash implies you are using some bit of information about the user (username, user_id number, etc). In this case, an existing user can figure this bit out about themselves, and check the cookie, then decompose it with a limited bit of work.

A completely 'random' key is significantly more secure, since it results in the individual having to guess correctly from the entire keyspace.

Since when was I suggesting security through obscurity? Or that you had to use user information to generate the hash (the table would have user identifiable information attached to the hash)?

What would you suggest on using to generate a completely 'random' key?
 
Since when was I suggesting security through obscurity? Or that you had to use user information to generate the hash (the table would have user identifiable information attached to the hash)?

What would you suggest on using to generate a completely 'random' key?

Having a 'secret algorithm' to generate the key is security by obscurity.

As for generating a completely random key, there are numerous cryptographic libraries with extremely good RNGs.
 
And you'd know that was what I was doing in server-side code how? :rolleyes:

(OH YEAH, because I told you here... crap!)
Because there are only so many things you can do. If I jack their cookie and their cookie doesn't work for me but works for them -- there are few reasons as to why that could be. It's easy to narrow down.

Whenever I write something, I ask myself, do I have any way to hack it? Do I have an advantage since I wrote it? If I do -- then I re-write it. I much prefer it to be secure because it's written secure, not because I'm writing in tricks hoping someone won't figure it out.

As to a good random source, if you're on a Unix system, /dev/random is pretty good. You can also grab pretty strong UUID's from /proc/sys/kernel/random/uuid

Code:
Last login: Tue Dec  8 12:11:27 2009 from ******
[root@clearprop ~]# cat /proc/sys/kernel/random/uuid 
9762e9ac-5e18-436a-a817-ab35f5a8d4b9
 
Because there are only so many things you can do. If I jack their cookie and their cookie doesn't work for me but works for them -- there are few reasons as to why that could be. It's easy to narrow down.

Whenever I write something, I ask myself, do I have any way to hack it? Do I have an advantage since I wrote it? If I do -- then I re-write it. I much prefer it to be secure because it's written secure, not because I'm writing in tricks hoping someone won't figure it out.

As to a good random source, if you're on a Unix system, /dev/random is pretty good. You can also grab pretty strong UUID's from /proc/sys/kernel/random/uuid

Code:
Last login: Tue Dec  8 12:11:27 2009 from ******
[root@clearprop ~]# cat /proc/sys/kernel/random/uuid 
9762e9ac-5e18-436a-a817-ab35f5a8d4b9


QFT.

An application isn't secure unless someone with access to the code couldn't break it.
 
Thanks to all this has been really good for me.

I think my biggest conceptual break through was that servers and browsers can have different definition definitions of a session. Thanks Troy.

I think I'm going to take Jesse's suggestion and have different privileges for a cookie login vs a password login.

This project is the start of the "club management" package. First thing is to keep track of plane usage and scheduled maintenance. I'm not ready to do billing from the usage because I'm not sure we can get 100% compliance right away.

I'm trying to make it easy for a smart phone to record start/end tach of the flight.

My next task is to get it from a dumb phone via sms (short email).

Joe

BTW, QFT = Quantum Field Theory or Quoted for Truth?
 
Thanks to all this has been really good for me.

I think my biggest conceptual break through was that servers and browsers can have different definition definitions of a session. Thanks Troy.

I think I'm going to take Jesse's suggestion and have different privileges for a cookie login vs a password login.

This project is the start of the "club management" package. First thing is to keep track of plane usage and scheduled maintenance. I'm not ready to do billing from the usage because I'm not sure we can get 100% compliance right away.

I'm trying to make it easy for a smart phone to record start/end tach of the flight.

My next task is to get it from a dumb phone via sms (short email).

Joe

BTW, QFT = Quantum Field Theory or Quoted for Truth?


Usually either "Quoted for Truth" or "Quite Fing True", I've heard it both ways.
 
Back
Top