[web] Session Variables

Started by
7 comments, last by Sander 18 years, 4 months ago
I've been thinking about php security issues recently... and I was wondering how secure session variables are. Are they stored server side or client side? And how exactly do they work?
Advertisement
The session data is stored server side. On the client side there is a session ID, which corresponds to that session data. The session ID is passed around in a cookie, or as part of the URL query string. Sessions will timeout eventually (how long depends on server settings).

The problem with passing the session ID around in a cookie is that not everyone has cookies enabled. The major danger with passing the ID around in the URL is that people may give a URL to a friend, or post or on a forum, or send it to a whole channel on IRC, or whatever else, and then anyone who goes to that URL may be able to access the original person's session data (ie, their login, if that's what you're using sessions for). You can (and should) check the requester's IP address, and check that it remains constant, which helps to prevent this (if the link gets passed to someone else, and they request the page but their IP doesn't match the one in the session data, then you can just dump the session). It's not secure though - if several people are accessing your site through a shared IP (for example, children at school, accessing your site through the school's connection), then the IP will be the same as well.
I can't remember if PHP's built in session handling deals with checking the IP address... you'd have to check (I suspect it doesn't, but I can't be sure)

And finally, the danger with session timeouts is that people will bookmark a URL with a session ID in it, and then go back to that URL and find a page that just says their session has timed out, instead of the page they were expecting (which means that if someone tries to, eg, look at their profile page with a timed out session, you should just redirect them to a login page that will take them back to the profile page once they've given login info)

Hope that helps,

John B
The best thing about the internet is the way people with no experience or qualifications can pretend to be completely superior to other people who have no experience or qualifications.
Hmm... Maybe it would be better if I explained how I'm using it...

I have a form set up to verify username/password. If the two match, then I set:

$HTTP_SESSION_VAR['ThisUser'] = $UserName;


And forward the user to the appropriate page. From then on out, every time the user accesses the pages, I say:

$UserName = $HTTP_SESSION_VAR['ThisUser'];


And all my mysql queries are based off $UserName. As far as I can tell, the SessionID doesn't get passed around in the URL. And if a page is bookmarked that requires special login privilages, and 'ThisUser' isn't set, then it fowards them to the login page. I also provide a 'log out' link which will kill the current Session ID for those who are concerned about their security.

Anyways, long story short... I was wondering if I should go to all the trouble of setting $HTTP_SESSION_VAR['ThisUsersPassword'], and check at every page to see if the password/username matches up. I want to ensure that hacking into someone elses account is as difficult as possible... but I don't know if this step helps out any or not.

What you could do is hash the user name with a secret value (such as a randon number hard-coded in the source, or the user's password), and store the user name and the hash in the session variable. Each time you read the variable, you verify that the hash is what it should be, which means that the secret was used to generate the hash.

Ideally, the hash is made from something like a large random number that only your server knows, a time stamp, and a user name. Then the user name and time stamp and the hash is stored in the cookie or session. You don't accept session cookies where the hash doesn't match, and you don't accept session cookies where the timestamp is older than X (which is the lifetime of your login session).

More information about various authentication schemes can be found in my authentication article.
enum Bool { True, False, FileNotFound };
Quote:Anyways, long story short... I was wondering if I should go to all the trouble of setting $HTTP_SESSION_VAR['ThisUsersPassword'], and check at every page to see if the password/username matches up.

No. Authenticate once and store the user id in the session.

Also, use $_SESSION.

session_start();$_SESSION['foo'] = 'bar';


That's all there is to PHP sessions these days.
Quote:Original post by Cygnus_X
And all my mysql queries are based off $UserName. As far as I can tell, the SessionID doesn't get passed around in the URL.

The PHP session ID is passed around in a cookie -- even with cookies disabled (at least under IE. I never tested that under another browser). You can make PHP pass it around in the URL as well. There's a settiong in the php.ini file to do that. It will rewrite every the URL's on your pages dynamically to do that. I never tried it though. In the absense of cookies I either I pass the session ID around manually, or I rely on basic AUTH_HTTP logins and keep track of sessions manually.

Quote:Original post by JohnBSmall
And finally, the danger with session timeouts is that people will bookmark a URL with a session ID in it, and then go back to that URL and find a page that just says their session has timed out, instead of the page they were expecting (which means that if someone tries to, eg, look at their profile page with a timed out session, you should just redirect them to a login page that will take them back to the profile page once they've given login info)


That's easily solved. When your script encounters an invalid session ID, discard the session, generate a new one and hand that new session out to the user. Write a message to a log somewhere if you're worried about security. Don't bother users with something as trivial as expired sessions or invalid sessions. Just recover silently.

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Quote:Original post by Sander
Quote:Original post by Cygnus_X
And all my mysql queries are based off $UserName. As far as I can tell, the SessionID doesn't get passed around in the URL.

The PHP session ID is passed around in a cookie -- even with cookies disabled (at least under IE. I never tested that under another browser).

The session ID cookie is set to be a "session only" cookie, meaning that it gets deleted when you close your browser. Those are usually enabled, even when longer term cookies are disabled.

John B
The best thing about the internet is the way people with no experience or qualifications can pretend to be completely superior to other people who have no experience or qualifications.
Quote:Original post by Sander
[...]
Quote:Original post by JohnBSmall
And finally, the danger with session timeouts is that people will bookmark a URL with a session ID in it, and then go back to that URL and find a page that just says their session has timed out, instead of the page they were expecting (which means that if someone tries to, eg, look at their profile page with a timed out session, you should just redirect them to a login page that will take them back to the profile page once they've given login info)


That's easily solved. When your script encounters an invalid session ID, discard the session, generate a new one and hand that new session out to the user. Write a message to a log somewhere if you're worried about security. Don't bother users with something as trivial as expired sessions or invalid sessions. Just recover silently.
A better solution, IMO, would be to send an HTTP redirect code to the same URL w/o a session ID at all. Very, very few sites need sessions for anonymous people that just want to view a URL, and making it a redirect would likely help search engines consolidate links to the same URL that differ only in session ID. I suggest delaying session creation until as late as possible, which for most sites means on submission of a logon form.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
I use sessions for all my guests, so I can track visitors and gather data that can help me improve my site. The way I handle bots is to detect them by their user-agent string and remove their sesison ID's from the URL so they can index the site properly. So, instead of attaching a bot's session to a session ID, I attach it to theiruser-agent string.

It depends on how much work you wish to put into tracking actually. Keeping track of your sessions manually does make it easier to do customized stuff like this. If you want some example code, check out the phpBB 3 code at phpBB's Area 51. I based my code off the way they handle bots. Ofcourse, I can't keep track of all bots that way, but I do handle all the mayor one's (Google, MSN, Inkotomi, etc.)

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

This topic is closed to new replies.

Advertisement