• Posted by Peter Haza
  • On November 6, 2006

  • Filed under PHP

  • 1 Comment

Session security in PHP, and how to improve it.

When you first start out with PHP, you soon realize that you need a way to save small chunks of data like client input across pages. There are two fairly simple ways of doing this in PHP. Sessions are useful for storing this data for shorter periods of time i.e per browser session while cookies are used to store the data more permanently. While cookies are saved on the client’s computer, sessions are stored on the server, giving the client a unique string which identifies their session. Hence sessions are arguably better for storing sensitive data, as there’s no way for anyone to tamper with it, unlike cookies which are just text files stored on the client computer. This is at least what many programmers tend to think today. Unfortunately, things are rarely this easy. This post is not going explain the vulnerabilities of sessions in great detail, but this great blog post explains the most common exploitations.

In this post I aim to nail the first problem mentioned by Harry Fuecks in his blog, shared web server. One of his suggested solutions is to use a database to store the sessions instead of normal files, and that’s exactly what we’re going to do.

First of all, you have to create the database table for our code to use. This is done by executing the following code either directly in PHP with mysql_query, or by using phpmyadmin or a similar tool:

CREATE TABLE IF NOT EXISTS sessions
(
    session_id VARCHAR(255) NOT NULL,
    session_expires CHAR(10) NOT NULL,
    session_data TEXT,
    PRIMARY KEY (session_id)
) ENGINE=INNODB;

This should create a table called “sessions”. The storage engine used here is InnoDb, but you can change this to HEAP to use an in-memory engine, or MyISAM which is the default MySQL table type or any other type supported by MySQL.

Now it’s time to configure a few settings to allow our script to access the database, these settings are located at the top of our script and should be self-explanatory:

// Mysql user
define( 'DB_USERNAME', '' );

// Mysql password
define( 'DB_PASSWORD', '' );

// Mysql database name
define( 'DB_NAME', '' );

// Mysql host
define( 'DB_HOST', null );

// Mysql host port
define( 'DB_PORT', null );

// Name of the session table
define( 'DB_SESSION_TABLE', 'sessions' );

That’s it! You’re done! You don’t have to call any special methods or functions to use this script. While the example below looks like its using sessions in the normal way the actual data is being stored in the database table. This is far more secure than using sessions in a shared web server environment. Don’t forget to call session_start():

require_once( 'mysql_session_manager.php' );
session_start();

// add a session
$_SESSION['this_is_a_session'] = 'omg, this is easy!';

// use it
if( isset( $_SESSION['this_is_a_session'] ) )
{
    // This will output "omg, this is easy!"
    echo $_SESSION['this_is_a_sesion'];
}

// delete session
unset( $_SESSION['this_is_a_session'] );

The script is written in OOP and PHP5. It requires a mysql database, version 4.1 or newer.

The code is released under the Creative Commons Attribution 2.5 License

Use 7-zip or similar to un-pack on a windows machine, or the unzip command or similar on linux.

Download: MySQL session manager

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

One comment

  1. Posted by Shay 22nd April, 2008 at 12:50 am |

    Freaking awesome :) Got me out of a tight spot with my host not supporting sessions correctly. Of course this is way more secure as well which is great on a shared host.

    Thanks for the class !

What do you think? Join the discussion...