PHP Session Management

Relates to PHP and Apache

I have rarely been content with session management in PHP. Since the web is stateless, a session must be maintained on a login site. The optimal way to achieve this is to place a session cookie, in the form of a session ID (a 32 byte alpha-numeric string), on the client. When the client has cookies disabled PHP appends the session ID to the end of each URI on the page. This latter practice comes with inherent complications. Server redirects must have the session ID hard coded into the source, which I sometimes find complicated to manage in complex validation and redirection scripts over multiple pages. Security Focus also highlights the major vulnerability of passing the session ID in the URI for PHP versions prior to 4.3.2.

When testing with cookies disabled I have also found browsing Back a number of pages can inadvertently destroy the session. If not coded carefully, the outcome can be a blank page, leaving the user confused and likely to just leave the site. My opinion is that the safest and most usable solution is to only allow the login process to proceed if cookies are enabled. If they are not a message is presented to the user with recommendations and advice on enabling session cookies and the implications of doing so.

So, the challenge is creating a user friendly process, where the user is informed immediately if they are unable to log in, and directions are given on enabling session cookies. The problem is that when a page first loads, the cookie is only passed to the client, so there is no way of knowing if the cookie has actually been set, and hence whether cookies are enabled. The following code snippet resolves this.


if (! isset($_COOKIE["PHPSESSID"]) && ! isset($_GET["PHPSESSID"]))
{  
  $sess_id = substr(SID,(strrpos(SID,"=")+1));
  $redirect_url = CMS . "init.session_" . $sess_id;
  header("Location: " . $redirect_url);
  exit;
}
elseif (! isset($_COOKIE["PHPSESSID"]) && isset($_GET["PHPSESSID"]))
{  
  $cookies_disabled = true;
}
else
{
  $cookie_disabled = false;
}

First the code tests for the cookie, and if it does not exists it looks for the PHPSESSID variable in the global $_GET array. If the tests fails, then the user has arrived at the page for the first time so it is not possible to tell if cookies are enabled or not. So, a server redirect is done to the same page (here defined by CMS in the initialisation file) with a custom string appended to the end. A custom string is used to enhance security, and the Apache mod_rewrite module is used to rebuild the URI as follows:


RewriteEngine On
RewriteRule init.session_([a-z0-9]{32})$ /cms/?PHPSESSID=$1

When the page reloads it runs the same test again. This time it passes the second condition and will only fail on the first condition if cookies are disabled. At this point a notice can be displayed to the user advising them that cookies must be enabled to actually log-in. To enhance the usability, if $cookies_enabled $cookies_disabled is true, a class is added to the login form, which overrides the normal CSS declarations, disabling the input fields and striking out corresponding labels. To aid users of assistive technologies, a title is also appended to each label stating that fields are disabled because cookies are required.

Perhaps this is common practice, but I recall in the past having trouble finding useful information for PHP session management best practices, and this seems to be an effective approach. The whole process is transparent to the user, and incorporating mod_rewrite to cloak the session id raises the level of security for the initial server redirect in which it is passed, as well as replacing the aesthetically displeasing URI string:

http://mysite/login/?PHPSESSID=sessionid

with the more comprehendable:

http://mysite/login/init.session,sessionid

If the initialisation variable session.name is changed to something other than PHPSESSID (or session_name(string) is called) then the URI becomes much harder to hack.

Posted on Monday, Nov 10, 2003 at 02:19:13.

Comments on PHP Session Management (6)

α comment

How can we detect if the user has cookie's enbaled though before continuing?

Posted by Fambi
Tuesday, Mar 22, 2005 at 13:50:01

β comment

$cookies_disabled will be false.

I would recommend looking at extending PEAR::HTTP_Session package for session management.

See this post - Pear HTTP_Session Package.

Posted by Tom
Tuesday, Mar 22, 2005 at 14:57:29

γ comment

Thanks for the code and explanation. Very helpful!

Posted by SpaceTaxi
Wednesday, May 25, 2005 at 19:33:14

δ comment

The only problem with header("Location: ….") is that google and other search engines will not follow them…

Posted by atx
Sunday, Oct 02, 2005 at 13:44:24

ε comment

i need some info about session $ cookies in php

Posted by kumar mithilesh
Thursday, Nov 10, 2005 at 06:20:09

ζ comment

Thanks for the usefull article

Posted by Dawid Joubert
Tuesday, Feb 21, 2006 at 00:16:04

Breadcrumbs Trail

[ Home ] -> TW Blog -> Nov 03 -> PHP Session Management
Site Map

The Severn Solutions website achieves the following standards:

[ XHTML 1.0 ] [ CSS 2 ] [ WAI AA ] [ Bobby AA ]

Page compiled in 0.113 seconds