How to: Regenerate Session IDs with Custom Session Handlers

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

Post Reply
User avatar
SystemWisdom
Forum Commoner
Posts: 69
Joined: Sat Mar 26, 2005 5:54 pm
Location: A Canadian South of the 49th Parallel

How to: Regenerate Session IDs with Custom Session Handlers

Post by SystemWisdom »

This is a solution I found recently to a problem I had trying to regenerate session IDs while using a custom session handler (namely MySQL).

I searched the net/forums to no avail, so I was forced to implement my own solution (which was quite simple, actually), and since I failed to find any suitable resources on this matter, I thought I would share my solution here.

Situation:
  • My website is on a Shared Host, so I implemented Custom Session Handling (via session_set_save_handler) using a MySQL database as a security measure.
  • To prevent from Session Fixation attacks I have been regenerating the Session ID (via session_regenerate_id) anytime a change in a users privelage occurs (like Logging in/out).
Problem:
Regenerating the Session ID when using a Custom Session Handler fails to maintain Session State. (The new session ID is not updated by the Custom Session Handler). Using both of these proposed security measures together seems fallible.

Solution:
Update the Database manually to contain the new Session ID while maintaining state! Simply create your own SessionRegenerateID() function, and call it anywhere you would normally call the built-in PHP equivalent (session_regenerate_id())

So basically, you would have (at a minimum):

Code: Select all

// Assuming DB connection is already established;
function SessionRegenerateID()
{   
    $szOldSessionID = session_id();
    session_regenerate_id();
    $szNewSessionID = session_id();

    $szQuery = 'Update SessionTable Set SessionID=\''.$szNewSessionID.'\' Where SessionID=\''.$szOldSessionID.'\'';

    // Ignore the DB abstraction
    $g_oDB->SubmitQuery( $szQuery );
    
    return;
}
The main part worth note is:
  • Get Old (current) Session ID
  • Regenerate Session ID
  • Get New Session ID
  • Update Database to reflect New Session ID


This solution is working great on my website, and I am surprised at the lack of information regarding this problem, considering it has such an easy solution!

Maybe tho, just maybe, this is a problem with the version of PHP which my host provides (4.3.10), and has since been addressed in later releases of PHP? (I know 4.3.10 has other security related holes, but it is up to my host to update, unfortunately)..

Anyway, I hope that this may help some people out!!
If you notice any problems (or know of any other resources) about this, please do not hesitate to post!! :D
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

A major reason most people haven't had such a problem is:
  1. most people use the built-in session system only.
  2. most people don't regenerate session id's, instead opt to destroy the session altogether and create a new one. (typically a log out kinda situation)
User avatar
SystemWisdom
Forum Commoner
Posts: 69
Joined: Sat Mar 26, 2005 5:54 pm
Location: A Canadian South of the 49th Parallel

Post by SystemWisdom »

So, in such a situation, do you feel that my proposed solution is acceptable?
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

I don't see anything wrong with it.
User avatar
SystemWisdom
Forum Commoner
Posts: 69
Joined: Sat Mar 26, 2005 5:54 pm
Location: A Canadian South of the 49th Parallel

Post by SystemWisdom »

Good to know, glad to hear it!! Thx for looking it over for me! :D
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

You solution makes sense, something similar is used internally by ADODB's custom session regen function.
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Post by AGISB »

The weird part is that I am also using a custom mysql session handler and session_regenerte_id() works just fine and Session State is remained.

Basically a new session_id with all the vars is stored in the mysql table. The old one stays and is destroyed by the garbage collection when it is expired.

Your solution might actually be much better as it immediately changes the session_id and the old one is gone.
User avatar
SystemWisdom
Forum Commoner
Posts: 69
Joined: Sat Mar 26, 2005 5:54 pm
Location: A Canadian South of the 49th Parallel

Post by SystemWisdom »

Hmm, what version of PHP do you use? I use 4.3.10 and it fails to maintain session state without doing what I suggested (it doesn't even create a new session row), but maybe it was fixed in later versions of PHP??
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Post by AGISB »

I am using 4.3.10 aswell. However I am not using php on a shared hosting so it might just be a php.ini issue.

However it seems that the changelog of 4.3.11 has some important bugfixes on some mysql functions.

http://www.php.net/ChangeLog-4.php
Post Reply