Felix Zaslavskiy
Web Developer, Programmer, Consultant
home  about  programming  resume  links
  Secure php sessions class for php5

Why we need more secure php sessions

SecureSession is a php5 class that adds additional security measures to the current php session mechanism. The php sessions have a number of weaknesses which makes them easy to attack using session hijacking or session fixation attacks. The main reason why this is possible is because the way php will accept any session id and if a session does not already exist for that session it will start a new session with that id. Lets say a clever attacker tricks a user to go to a web-page through this url: http://www.banksite.com/login.php?PHPSESSION=madeupbyattacker. If the bank site is written without precaution there is pretty much a session_start() call at the top of every application pages. Before even loging in the user will already start using a session with the session id provided by the attacker. This is what is known as a session fixation attack and it is possible with php sessions.

Preventing session fixation attacks with regenerated id

The best way to stop a session fixation attack is by changing the session id right after a privilage level of the application has been increased. Typically right after the password of the user has been verified a session_regenerate_id() is called. Although this method is pretty good at stopping session fixation it does not address cross site scripting attacks.

Allowing session ids created only by the server

One way of making things harder for the attacker is to not let them create any random session id. Only the server has to be able to create valid session ids. The SecureSession class does not actually create session ids but lets PHP generate them. What the class does is create a verification token for a session id and stores it in a cookie. Only the server can generate a token that is unique to any particular session id. What this also does is make things a bit more difficult on the attacker since he would have to setup a user not only with a new session id but also with a valid verify token. The way that verification token is generated is with a use of a MAC or message authentication code. A MAC is a way to know that any particular string was created only by the person who had knowledge of a secret. For example here is a simple way to do this:

$mac = md5( $sessionid . $secret_key );
So this way using a MAC we know that a certain message could have only been signed by the server because the knowledge of secret key is required. Of-course we don't want to use such as simple way of generating a MAC in our code. For that we use a more secure hmac algorithm:
$mac = mhash( MHASH_SHA1, $sessionid, $secret_key );
In essense the MAC is the verification token.

Adding in User agent check

An attacker can still get a hold of a valid session id and a verification token simply by starting a session with the server. In order to not make it as simple for the attacker we want to include the user browser's user agent string as part of the verification code. This makes it harder for the attacker since he would have to guess the User agent of the user before getting a valid session id.

Putting all our goals into an implementation

One way to accomplish all these goals is to write a wrapper function around session_start(). SessionSecure::start() is a static method that replaces session_start(). Another very useful function that we have a wrapper for is session_regenerate_id() and the replacement is SessionSecure::regenerate_id(). In addition to starting a session a clean way of ending a session SessionSecure::kill() method will destroy the php session, remove session cookie and remove the verification token cookie from teh users browser.

Here is some sample code using SessionSecure class:

	try {

		// Configure the class to get the secret key on the server
		SecureSession::setServerKey( new ServerKeyFile( "./key.txt" ) );

		// Our wrapper around the session_start()
		SecureSession::start( );

	} catch ( InvalidSession $e ) {

		// In case an invalid session id is passed by the client
		error_log( "Invalid session id caught", 0 );
		header( "Location: login.php" );
		exit;
	}
		

Like already mentioned SecureSession is a php5 only class. You may download the class file by right clicking on it and using "Save As" function in your browser.