什么时候以及为什么我应该使用 session_generate_id() ?

为什么以及何时应该在 php 中使用 session_regenerate_id()函数? 我应该总是使用它后,我使用的 session_start()? 我读到我必须使用它来防止会话固定,这是唯一的原因吗?

68391 次浏览

You should use session_regenerate_id() in order to stop session hijacking and session fixation.

From this Security.SE answer:

Session hijacking refers to stealing the session cookie. This can be most easily accomplished when sharing a local network with other computers. E.g. at Starbucks. Example... a user with session Y is browsing James's website at Starbucks. I am listening in on their network traffic, sipping my latte. I take user with session Y's cookies for James's website and set my browser to use them. Now when I access James's site, James's site.

From this webpage:

Session Fixation is an attack technique that forces a user's session ID to an explicit value. Depending on the functionality of the target web site, a number of techniques can be utilized to "fix" the session ID value. These techniques range from Cross-site Scripting exploits to peppering the web site with previously made HTTP requests. After a user's session ID has been fixed, the attacker will wait for that user to login. Once the user does so, the attacker uses the predefined session ID value to assume the same online identity.

When To Use

When user is editing / updating some important inputs (changing passwords, credentials, forgot passwords etc.) which may compromise site security or privacy policy.

See also:

PHP Security Guide: Sessions

Session Fixation(Nice read)

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:

You can use it for better security.

With this way you are creating session id's for one time use.

Lets say your user session id is = 3

Some hacker hacked you client and get their session_id. So hacker can use that cookie to use their session.

If you have code like

session_start();
session_regenerate_id();

you are able to change their session each time they using your website.

Now hacker gets sessionid = 3

but you have changed session after he use that so your

user have sessionid=4 // auth

hacker have session=3 // null

But there is a little point lets say you are using regenerate method and your client just login to website and close browser or inactive. Your client have sessionid=4 and if hacker gets cookies at that part they will have same sessionid.

As explained above this way you can protect your client from data sniffing on one way, but still its not will fix this issue for good.

But its will be way much secure if you use SSL enc.

Sorry for bad english.

A simple use case:

// User visits a webshop
$shopcart = new Cart();

A session is started and an entry is made in the database. The user's shopcart is identified by his session id.

// User orders items
$shopcart->add('123', 20);
$shopcart->add('124', 18);
$shopcart->add('127', 5);

For each product added, a record is made in my shopcart table. Also identified by the session id.

// User saves cart in order to use it later
$shopcart->save();

The user decided to save his cart. It is now being attached to his user id.

// Regenerate session id for user to be able to make a new cart
session_regenerate_id();

The sesssion id is regenerated and the user can now start over creating another shopcart.

I think the issue of session poisoning has been covered pretty well.

To answer the "When should I use this?" portion, it's important to step back and consider what your application is doing with the session. Or, to put it another way, this is the key security question you need to answer

If someone got a hold of this session what would they gain?

If all you do is track otherwise anonymous data (user comes to site and you use it to track their visits) then there's little reason to regenerate a session. A hijacker wouldn't gain anything of value by grabbing that session.

Lots of sites offer logins, however. A login changes lots of things. I can access my profile. I can change settings. So a hijacker might want my account access, especially if normal and admin users all use sessions to manage the login. So when people come to my site and log in I regenerate the session. It adds an extra layer of security that my newly logged in user is less likely to get hijacked.

Any time we add critical data to a session you should consider regenerating the session ID. If you need to harden your application against fixation then a random regeneration can be useful but I would NEVER regenerate on every request. By default PHP stores sessions in files on the local disk. You're adding a lot of disk I/O to mitigate what is a relatively small attack vector. If you really need more security I would advocate going full HTTPS over regenerating on a regular basis (HTTPS makes fixation very hard to pull off).

Why should I use session_regenerate_id?

You should use it to prevent session fixation.

When should I use session_regenerate_id?

Whenever the authentication state changes, that's mainly on login and logout.

Example

Bob sits at a public computer and by browsing stackoverflow.com he opens a new session there. The session ID is saved in a cookie (with httpOnly flag to prevent access through javascript). Let's imagine Stack Overflow had HTTPS always enabled and also the secure flag set for the cookie.

How can we steal the session now?

Bob writes down the session ID. He leaves the computer without closing the browser. Now Alice comes to this computer and sees Stack Overflow is already loaded. She logs in now.

Now we're at the stage where you should use session_regenerate_id. If you don't create a new session ID here during login, Bob could use the previous session he had written down to access Alice' session and would be logged in as Alice now.

session_regenerate_id(): Cannot regenerate session id - session is not active

if(session_status() == PHP_SESSION_ACTIVE)
{
session_regenerate_id();
}