When and Why I Should Use Session_Regenerate_Id()

When and why I should use session_regenerate_id()?


What is session_regenerate_id()?

As the function name says, it is a function that will replace the current session ID with a new one, and keep the current session information.

What does it do?

It mainly helps prevent session fixation attacks. Session fixation attacks is where a malicious user tries to exploit the vulnerability in a system to fixate (set) the session ID (SID) of another user. By doing so, they will get complete access as the original user and be able to do tasks that would otherwise require authentication.

To prevent such attacks, assign the user a new session ID using session_regenerate_id() when he successfully signs in (or for every X requests). Now only he has the session ID, and your old (fixated) session ID is no longer valid.

When should I use session_regenerate_id()?

As symbecean points out in the comments below, the session id must be changed at any transition in authentication state and only at authentication transitions.

Further reading:

  • http://php.net/session_regenerate_id
  • https://www.owasp.org/index.php/Session_fixation
  • http://en.wikipedia.org/wiki/Session_fixation
  • https://wiki.php.net/rfc/precise_session_management

session_regenerate_id() vs session_id(randomString)

OK, so I did some testing to find the differences in the three different options (session_id($id) after session_start(), session_regenerate_id() and session_regenerate_id(true)). This is the result of what actually happens:


session_id($id) after session_start

Calling the session id function after session_start will change the session id. At the end of the page load, the current session contents will write a new session file. This will leave the old session file as well and it won't be updated with any changes. However, session_id doesn't send out a new session cookie. This is done by session_start, even when session_id is called before session_start. On the next page load, the old session id is passed and loaded with the same data as the start of the last page load (new session changes would have been saved to the new id).


session_regenerate_id() and session_regenerate_id(true)

session_regenerate_id() will create and change the session id, transferring the session to the new file and send out the cookie. Passing true as an argument will also delete the old session file, omitting the argument will leave it.


As far as session fixation, both session_id($id) and session_regenerate_id() would actually be worse as you are creating new sessions while leaving the old session files around to be hijacked. The only option that might help with fixation would be to call session_regenerate_id(true) passing the argument.

Explanation for session_regenerate_id() proper usage

Regenerating the ID protects against session fixation, where an attacker takes someone else's session ID as their own by adjusting the session ID in their cookies.

As an example situation:

  1. I go to www.nsa.gov on Edward Snowden's computer while he's at lunch.
  2. I note his PHPSESSID cookie.
  3. I wait for him to log in to the super-secure system.
  4. I can now set my PHPSESSID value to his and have his access.

Regenerating the session on login and privilege escalation means the ID I'd grabbed is now useless.

Should I regenerate_session_id on every page?

You may use session_regenerate_id to prevent session fixation attacks, in which the attacker learns the session ID of a given user then "hijacks" that session ID to act in place of the user.

However, care must be taken. For one, you have to consider asynchronous requests. If you have many concurrent requests coming from a user, you'll want to avoid a situation where one script is using session data when another tries to regenerate - one script is using data that the other is trying to destroy.

Also, this does add overhead. Regenerating every request is probably an overkill. Instead, try keeping a request counter; every 10 requests (or so, arbitrary selection), regenerate the ID.

Be sure to pass the argument as true - you don't want or need the old session data sitting around (keeping in mind, still, concurrent requests). See the (docs) for more information.

All that said - this mechanism is a sort of "micro-enhancement" that will give you more false sense of security than actual security. Session-fixation attacks are not very common, especially if you're already taking other measures to bolster security. Nothing can replace, for example, using HTTPS for secure connection; nothing can replace password complexity requirements.

What are session_id, session_regenerate_id and session_name used for?

No, you don’t need to use them. In general all you need is

  • session_start to start the session handling, and
  • session_destroy to destroy the stored session data (this does not modify $_SESSION), and
  • session_unset to reset the $_SESSION variable (but you can also do $_SESSION = array()).

session_id and session_name are to get and set the current session ID and session ID name (default is PHPSESSID). session_regenerate_id can be used to regenerate/change the session ID of the current session. This might be useful if, for example, you want to refresh the session ID every 10 minutes or after changing the state of authenticity of a user associated with a session.

Properly regenerating session ID's


  • The safest regenerate session is session_regenerate_id(true);
  • The (true) will delete the existing session and it will create new

    one
  • To keep new session and old session until its expiration use

    session_regenerate_id();

Is PHP's session_regenerate_id() collision free?

Yes. session_regenerate_id calls session_create_id so it's also collision free:

sid = php_session_create_id((void**)&data);

session_regenerate_id and security attributes

In your local folder PHP.ini settings (typically called user.ini and found in your root HTML directory of your website account), you can set the PHP.ini values:

session.cookie_secure=1
session.cookie_httponly=1
session.use_only_cookies=1

and this will mean any usage of session cookies by this account (this website) will conform to the above requirements.

This is much better than coding these reqirements in to your scripts as this can be easily missed or overlooked down the line.

Your script can then be:

session_start();
...
session_regenerate_id(true);

And you will know everything else will be taken care of automatically.


You can read a little more about session security HERE.



Related Topics



Leave a reply



Submit