Tell me more ×
IT Security Stack Exchange is a question and answer site for IT security professionals. It's 100% free, no registration required.

In PHP, I'm not sure if I should start the session before destroying it when a user wants to log out.

session_start();
session_destroy();

Is there anything else that needs to be done?

EDIT: I reposted on Stackoverflow here but I'm still not fully understanding.

Basically I'm asking, you tell me, what needs to be done at logout? I know since I create a session using session_start() at login I need to call session_destroy(). Some SO pages say to call session_regenerate_id(true) and session_unset() too and I don't get why.

share|improve this question
Celeritas, I assume you're asking from a security PoV? Can you elaborate what threats or attacks you're worried about here? A bit more context would be good too. – AviD Mar 7 at 10:38
@Celeritas, session_regenerate_id(true) is important so that even if an attacker steals a token, he only will have to use it in a short period of time. When the session id is regenerated, he need to steal again. – void_in Mar 8 at 15:15
session_unset() is important since as @TildalWave pointed out, session_destroy() do not unset the session cookie. So if the attacker is in possession of the session cookie or have access to the browser of the victim, he can replay the session cookie and authenticate to the application. Further details in the white paper linked in my answer. – void_in Mar 8 at 15:18

4 Answers

No, you shouldn't be doing this and not just for minimal performance gains. I realize what made you think it'd be a good practice, but let's analyze these two quotes from the PHP manual a bit more:

session_start() creates a session or resumes the current one based on a session identifier passed via a GET or POST request, or passed via a cookie.

session_destroy() destroys all of the data associated with the current session. It does not unset any of the global variables associated with the session, or unset the session cookie. To use the session variables again, session_start() has to be called.

OK, that's clear. You also mention in your post on SO that there's a chance that the user can directly navigate to this URI where you'll be running this code from. You really shouldn't be doing this and you should at the very least check user log-in data and the referrer string before starting the session and delete the session whenever user state changes. But let's say you didn't change your code and we can navigate to the URI in question. Now imagine this scenario:

  • I have access to one of your legit user's computers, his/her network, can access your web application through same IP, and can collect his/her client-side session data
  • I make a POST or GET request with no session data to your URI running this code
  • I manually add these session fragments (session cookie, user-agent string) that I have access to in my modified browser

Voila!

All of this is really easy to do and plenty of people with direct access to targeted user's computer would have the means and reasons to do such a thing, if they only had the knowledge to. And you're slightly lowering that bar.

Let's see what will happen.

session_start() will be called before the session was invalidated on your web server (which happens on session_destroy()), effectively creating a new user session. I can then replace my new session data with the old (stolen) one, and your web application will have (based on my user-end session data) no reasons to suspect I'm not the user the session was created for in the first place. It will resume as if I was the previous user I stole session data from.

So how does this differ to session hijacking when using session handling routines in their intended order?

In a long discussion with @Xander dissecting PHP session handling routines, we've come to the conclusion that it doesn't change much anything in that sense. However, you also gain nothing by doing it so, and might result in breaking functionality of any third-party user session framework, if your PHP application depends on in. Quoting your related SO question "I'm concerned that if a user directly navigates to this page there may be an error destroying the session" does expose another concern, that you're essentially enabling exploiter a look into your user-end session data structure for free, without any user authentication before creating it. Saying "But I'm deleting it immediately!" doesn't really apply in this sense, as session_destroy() "...does not unset any of the global variables associated with the session, or unset the session cookie." Saying it differently:

You just made session hijacking slightly easier, not the other way around!

TL;DR - So in short, you'll have to do it 'the boring, standard way' as that's in what order these two session changing routines were designed to run.

share|improve this answer
Hm authorization exceeding authentication.Interesting:) – Saladin Mar 7 at 20:39
@asadz - yes, but not exceeding, but completely bypassing it. – TildalWave Mar 7 at 20:40
Can he just get a return on destory() function every time a new session is going to start?And take action accordingly. – Saladin Mar 7 at 20:44
@asadz - The point is that you should make sure the server end invalidates user session created at any point the user state changes. Failing to do a single step opens up a world of possibilities to exploit it. Sure, you could prevent session_delete changes on the end-user computer, but that doesn't stop it from processing server-end and invalidating the session (making any end-user fragments pretty much pointless). – TildalWave Mar 7 at 20:47
1  
Thanks for explanation. I give you +1 for this. – Saladin Mar 7 at 20:50

It's totally dependent on what your specific application actually does, but one general additional guideline that I'd suggest would be to destroy any cookies you've created.

share|improve this answer
Is it necessary to session_start()? – Celeritas Mar 6 at 23:38
I'm not a PHP guy, but I can't see why you would need to. Looking at the docs however, you do also need to destroy the session id to fully log out a user. It doesn't look like it's eliminated by session_destroy(). – Xander Mar 6 at 23:47
Maybe this would be a better fit for Stackoverflow? – Celeritas Mar 7 at 0:00
Yes, I suspect you're right, it probably would be a better fit there. – Xander Mar 7 at 0:01

If you follow OWASP there is a lot on how to secure connections and maintain a secure session state. They would give you some nice explanation on how to securely initiate a new connection. Some are

  1. Do not allow the login process to start from an unencrypted page. Always start the login process from a second, encrypted page with a fresh or new session token to prevent credential or session stealing, phishing attacks and session fixation attacks.

  2. Consider regenerating a new session upon successful authentication or privilege level change.

  3. Limit or rid your code of custom cookies for authentication or session management purposes, such as "remember me" type functionality or home grown single-sign on functionality. This does not apply to robust, well proven SSO or federated authentication solutions.

Here is the test for cookie re-use / fixation

share|improve this answer

Acadion Security has published a white paper about how to securely implement user sessions in a web application. Not only the session should be destroyed on logout, but session should be destroyed on:

  1. Timeout
  2. Logout
  3. Unencrypted Transfer
  4. Wrong Origin
  5. Dual Login
  6. Password Reset
  7. User Agent Change
  8. Occasional Session Regeneration

Details can be found in the paper here.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.