Skip Navigation

Better Sessions

 
Sessions have inherent problems, as most developers know. A session ID can be easily hijacked, and that can cause major problems with security in a website. There are ways around this - in PHP you can set up sessions so that the session ID can only be transmitted using cookies, but then you prevent those without cookies from logging in. One way around this problem is to tie your session ids to the user's IP address.

So here's a short tutorial explaining one technique for doing this. It is split into two parts - the first is the generation of the session ID. The second is to be included on every page, and is to re-verify the session ID of the user. You should also consider adding a page when someone tried to use an expired session on which is explains that if they have reconnected to the internet they may have to re-login (those with dynamic IP addresses for example).

Part One - Starting the Session

I am assuming at this point that the user has entered their username and password and these have been verified as accurate.

If you are using a version of PHP earlier that 4.2, you will need to seed your random number generator with the following line before the code below.

srand((double)microtime()*1000000 );
$rand=rand(1,9);
$session_id=$rand.substr(md5($REMOTE_ADDR), 0, 11+$rand);
$session_id.=substr(md5(rand(1,1000000)), rand(1,32-$rand), 21-$rand);
session_id($session_id);
session_start();

The above has generated a session id as follows:

  • A random number is created between 1 and 9 and used as the first character of the session id
  • The first (11 plus random number) characters are taken from encrypted version of the IP address
  • The remaining characters needed to create a 32 character session id are taken from a random section of the encrypted version of a random number between one and one million.


That number is then assigned to the session as the session ID. You can treat it exactly as a normal session id and call it the same way using PHP's built in session functions.

Part Two - Verifying the Session is valid on each page

It's all very well having a system set up to check whether a user is logged in, but we want to be sure that the user we think is using the site is the right person, and not someone who has hijacked their session id. So, we re-verify the session on each page we want to be secure, with the following function:

function session_verify() {
session_start();
if (substr(md5($REMOTE_ADDR), 0, 10+substr(session_id(), 0, 1))==substr(session_id(), 1, 10+substr(session_id(), 0, 1))) {
// Session Valid
$session_valid="yes";
} else {
// Session Not Valid
$session_valid="no";
}
return $session_valid;
}

Simply call this function however you like from whichever page you like and it will determine for you whether or not your session ID is authentic for the user.

And there we have it - more secure sessions. This is not a complete session management system (personally, I tie sessions to a MySQL database as well), but does mean that session hijacking is extremely difficult (in order for a hacker to hijack a session, they need to grab the session id of a user and spoof their IP address).
 

Syndication

If you like this post, subscribe to my full feed or partial feed.

 

14 comments (Add Yours)

You can keep up to date with this discussion by subscribing to the RSS or Atom feed.
 
Petr
Czech Republic #1: December 16, 2003
If you rely on IP address you can get into trouble. Some ISP use more proxies and the same client can have different IP during the session. I had to change my booking form because there were relatively a lot of people who could not get through the whole booking process because I tied the session id on an IP address. I don't recommend it.
awesome tutorial!
Gaurav
United Kingdom #4: July 31, 2004
why not use an ip address to verify if its the same user after logging in, then check if the session id fits the same session id being passed on each page thats in the sql table...
Setup requires for session.autostart in the php.ini file to be turned off.
J.H
United Arab Emirates #6: May 5, 2005
isn't this better & simple :
$_SESSION['IP'] = $_SERVER['REMOTE_ADDR'];

TO MAKE SURE OF THE SESSION :
if($_SESSION['ip'] !== $_SERVER['REMOTE_ADDR'])
{
// GO OUT
}
Laurent
France #7: March 15, 2006
I tend to disagree. This is article does *not* explain how to have a better session, it show how to create a *broken* session. You can't rely on IP as statued by Petr.
What about Aol users. I heard their ip address constantly changes from webpage to webpage?
Steve
United States #9: April 25, 2007
Who cares about them. AOL users sux. Don't support their nonstandardized cr@p.
It seems a viable option. The IP address I would tend to not do, however you can compare other information such as the browser etc. The odds in getting through all the different matches would be slim.
Gavin
Unknown #11: November 20, 2007
Many ISP's proxy or use few public addresses, so most of their users will seem to have the same IP address. Creating a session from an IP address is a bad idea.
If I'm not mistaken, this script doesn't tie a session ID to an IP address in the sense that each IP can only have one session ID -- it merely uses the IP as *part* of the session ID, so that it can always check whether the session user is still coming from the same IP. This would open the door for exploiters coming from behind the same gateway, but in cases like that the exploitee could walk down the hallway and punch the exploiter in the face.
Not every solution is right for every person. This could have applications in a smaller, more controlled, and more secure site. From experience, 'IP hopping' by users in a shared pool is rather common. Out of a site I run with 10,000 solid users, perhaps 500 use AOL (hey, they're a relatively bright bunch), so at any given look-see of online users, there's almost always one online whose IP changes with every click (fills up the logs!) This is a good solution and addition to the site, but its scope is not for the general public.
The proxy issue is definately a problem if you are running a comercial website where you can't just choose your users. I used to run into problems with AOL and Yahoo DSL users a lot and it took me a while to figure out why.

I've heard of some developers just verifying the first octet or two. It's not as secure as verifying the whole ip but it's better than nothing and it usually takes care of the proxy problem.

A more ambitious developer could attempt to identify the isp and adjust accordingly if it's known to use multiple proxies. You could start by just checking for the big well known ones like AOL. To find the rest record the ip-addresses anytime a session is dumped due to the ip changing. Then as users complain, you can use these records to discover the rest. This would still inconvenience some users but if you take care of the big ones up front and keep on it they will probably be very much in the minority.

 

Post Your Comment

 
Only the name and comment fields are required.
 

Live Comment Preview

 United States #15: 1 minute ago

Web Design, Development and Marketing