Jump to content

session_regenerate_id() and race issue


tork
Go to solution Solved by objnoob,

Recommended Posts

I notice that when I've regenerated a session_id(), that the original session remains on the server while the new one is added. I'd like to know how I can remove the old session. I may be mistaken, however I believe the issue is called racing, and is that the old session could (rarely, but possibly) be re-used if the session_id algorithm created it again, thus allowing the second user to have access to the first user's old session.

1. Do I understand the issue correctly?

2. How do I remove the old session?

Link to comment
Share on other sites

Thank you. However, I need to be more specific. Is there any way of deleting a session file by naming it? EG (and I know the parameter must be void): session_destroy(session_id). Clearly this won't work. What I need is a non-regenerate method of destroying particular sessions by their session_id. If it's not removed, then user data may be picked up via the race issue. Any ideas anybody?

Link to comment
Share on other sites

You should avoid regenerating session IDs. If security concerns you, you should be using HTTPS and ensure the session cookie is transmitted over a secure connection. 

 

http://php.net/manual/en/function.session-set-cookie-params.php  - see secure parameter

 

However, if you insist on regenerating the ID... configure your session.gc_* settings to increase garbage collection, and let the garbage collector dispose of those elderly sessions kept alive to mitigate race conditioning. 

If you're eager to reinvent the wheel and handle garbage collection yourself, you can call session_id to manually set the id the session_start function will use. 

 

Don't reinvent the wheel!

Link to comment
Share on other sites

...and? You're going to ignore a mechanism to prevent session hijacking because of the remote chance that a user might submit two simultaneous requests in such a way that one attempts to access the session information in the microsecond between the other closing the old session and deleting the file? Because that's literally what happens: one statement to close and unlock the file and the very next statement deletes the file.

 

Which isn't to say that you have no recourse in case the old session isn't deleted: session_regenerate_id() will raise a very nice "Session object destruction failed" warning (and return false) if that happens.

Edited by requinix
Link to comment
Share on other sites

Correct me if I'm wrong, but if I session_regenerate_id(false) and set my php.ini gc parameters to a high probability to kick in after a short maxlifetime, would this not minimize the risk of a race condition?

 

I tested this, yet my session file has not been removed after 240 - I set the probability at 100% (100/100) and maxlifetime at 240 secs. Now I'm getting confused ;)

Edited by tork
Link to comment
Share on other sites

  • Solution

Sorry, I should have answered sooner.

 

I notice that when I've regenerated a session_id(), that the original session remains on the server while the new one is added. I'd like to know how I can remove the old session. I may be mistaken, however I believe the issue is called racing, and is that the old session could (rarely, but possibly) be re-used if the session_id algorithm created it again, thus allowing the second user to have access to the first user's old session.

1. Do I understand the issue correctly?

2. How do I remove the old session?

 

You have a misunderstanding of the issue.

A race condition is created when 2, almost simultaneous, requests are sent to the server with the current session id, and you're actively regenerating session ids and immediately deleting the old session.

These two requests are literally racing!  The winner, if you will, will trigger the id regeneration and delete the old session. This leaves the second request using the old session id that points to an invalid / nonexistent session.

A new *empty* session is created, for the second request, using the old session id.

 

IMPORTANT: If the second request happens to call session_id that is setting the id in any way, shape, or form, a new cookie is sent with the response that will overwrite the recently regenerated session id. Now the session data is up shit's crick and your user is without a paddle. 

Link to comment
Share on other sites

Thanks for that clear explanation.

 

As a matter of understanding session parameters, I set the probability at 100% (100/100) and maxlifetime at 240 secs. Then I ran a session and timed the session record for when it got deleted. I expected it to delete in 4 minutes from the start of the session (session_start()). Yet it's been there much longer. Am I missing something here?

Link to comment
Share on other sites

...and? You're going to ignore a mechanism to prevent session hijacking because of the remote chance that a user might submit two simultaneous requests in such a way that one attempts to access the session information in the microsecond between the other closing the old session and deleting the file? Because that's literally what happens: one statement to close and unlock the file and the very next statement deletes the file.

 

Which isn't to say that you have no recourse in case the old session isn't deleted: session_regenerate_id() will raise a very nice "Session object destruction failed" warning (and return false) if that happens.

 

There are other ways to prevent session hijacking!

  • Create a token that is strictly transmitted through the URL.
  • Check if IP and/or User-Agent of the client have changed, if so, force re-authentication. ( not that I rec ommend this, but... )
  • Configure php.ini properly.
  • Always call session_set_cookie_params ( $secure=true, $httponly=true ) before calling session_start.
Link to comment
Share on other sites

Thanks for that clear explanation.

 

As a matter of understanding session parameters, I set the probability at 100% (100/100) and maxlifetime at 240 secs. Then I ran a session and timed the session record for when it got deleted. I expected it to delete in 4 minutes from the start of the session (session_start()). Yet it's been there much longer. Am I missing something here?

 

Either --

  1. You're not deleting the session cookie, and when you come back with that cookie -- a new session is created, but with the same session id. this isn't the same ol' session... it's a new session with the same id.
  2. You're accessing the active session using session_start and the session file lifetime is resetting.
  3. The garbage collector isn't firing because you're not making a request that calls session_start().
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.