Session Cookies faulty in IE8

I didn’t quite know what to call this post, because I really want it to show up in search engine results. Why? Because I couldn’t find the solution online and it needs to be there! I guess the heading could have been any of the following:

  • Cookies broken in IE8
  • Session variables disappear in IE8
  • IE8 not keeping session data
  • IE8 loses cookie
  • IE8 loses session on session_regenerate_id() call
  • IE8 has more mood swings than a 2 year old girl

Now you have a better idea what this post is about.

I enjoy writing about an Internet Explorer problem, not because it is a fun problem, but because I know somewhere out there someone will have the same problem and we can share solutions!
:)

Get to the point!

I had a log in system on a site of mine that always worked, but we then started seeing some problems in Internet Explorer 8. The problem was that after log in, IE8 would "lose" the cookie and the user won’t be logged in. The session, however, still existed. Now the really funny part is that it only happened on some IE8 browsers, not all of them, and unfortunately my IE8 was one of those that worked, which made debugging a pain. This problem did not occur in Firefox or Chrome, or even in earlier versions of IE (IE6 worked!); just some IE8 browsers.

So after sleepless nights, one of my bright colleagues asked whether it could be the session_regenerate_id call that I use for security reasons… and it was! So here is the punchline:
The php function session_regenerate_id causes some IE8s to lose their cookie. This occurs if you do a redirect after logging in. What happens is that the browser redirects before it can update its cookie locally, causing the cookie SID to not match your session ID after redirecting.

Why use session_regenerate_id() in the first place?

If you don’t know why to use this function, then unfortunately this post won’t help you… yet. You really should be using it (or a similar method) as it’s a must for log in systems that have any form of security. Basically you call the session_regenerate_id() function right after log in or log out (actually, whenever there is any change in the privilege level of the current user) to prevent session hijacking — that’s when a hacker uses another user’s session ID to pretend that he is that user.

My login code that was giving me trouble looked something like this:

        function login() {
            $this->user['logged_in'] = true;
            session_regenerate_id(true);
        }

Nothing special, I just set my user as logged in and gave him a new session ID, but as explained, it left me with a few headaches.

The solution

Now as I’ve mentioned, I don’t have a clean workaround yet. All the workarounds I could find on the internet did not work. But here is our do–it–yourself solution:

  • First save the current session data in a variable.
  • Now close the session so that you can update the session ID.
  • Generate a random hash and set your session ID to that hash.
  • Restart your session
  • Finally, set your session data equal to the stored variable (your old session data)

That’s it, a very simple workaround:

        function login() {
            $this->user['logged_in'] = true;
            $old_session = $_SESSION;
            session_write_close();
            session_id(sha1(mt_rand()));
            session_start();
            $_SESSION = $old_session;
        }

Now until someone comes up with a cleaner solution this will keep your website working even on those weird IE8s.

Please comment if you know of another cleaner solution, thanks!

9 Responses to “Session Cookies faulty in IE8”

  1. Edward Halls says:

    I have had this same problem and in our case it was due to duplicate cookies being set regardless of the browser. This problem only became apparent as it seems IE8 uses the first session cookie set and not the last as in Firefox.

    This resulted in IE8 matching the session to the now destroyed one.

    To remedy this I used the equivalent of :

      //Regenerate Session
      session_regenerate_id(true);
    
      // Delete all residual session cookies and set the new session
      // cookie for https. I believe these two lines are the only ones you need to fix the issue.
      setcookie(session_name(), session_id(), time()-100000);
      setcookie(session_name(), session_id(), 0, '/', 'example.co.uk' ,TRUE);
      
       //Equivalent of a page refresh occured and then the following was executed.
    
      // Ensure session changes are written to disk prior to header redirect.
      // This in turn ensures that the new session id cookie was set in the header.
      session_write_close();
    
      header('Location: '.$place);
    
  2. Ed says:

    I was having this same problem. PHP sessions were not persisting IE8, but they were in every other browser (Chrome, Firefox, Opera, Safari). Nothing worked. I tried everything from proper headers with P3P directives, cookie manipulation, resetting session id’s, setting cookies to expire way in the future, blah, blah, blah.

    Here is what finally worked (and I don’t know why it works), but this was the culprit…

    After days of debugging, I found that my script had an image tag that had a bad src reference in it, like this:

    In other words, the src reference was empty/blank. THIS WAS THE CULPRIT TO MY WHOLE PROBLEM. I don’t know why, but after putting in an actual image location like this:

    After correcting the empty src reference, everything worked fine and the PHP session was being set properly even in IE8. Believe or not, this was the reason behind the PHP session not being set.

    I still have no idea but it worked fine after this. I’ll have to research why this would cause a problem like this. If anyone knows why, please post the answer.

    I hope this helps someone. :-)

  3. Ed says:

    I was having this same problem. PHP sessions were not persisting IE8, but they were in every other browser (Chrome, Firefox, Opera, Safari). Nothing worked. I tried everything from proper headers with P3P directives, cookie manipulation, resetting session id’s, setting cookies to expire way in the future, blah, blah, blah.

    Here is what finally worked (and I don’t know why it works), but this was the culprit…

    After days of debugging, I found that my script had an image tag that had a bad src reference in it, like this:

    <img src="">

    In other words, the src reference was empty/blank. THIS WAS THE CULPRIT TO MY WHOLE PROBLEM. I don’t know why, but after putting in an actual image location like this:

    <img src="./images/myimage.gif">

    After correcting the empty src reference, everything worked fine and the PHP session was being set properly even in IE8. Believe or not, this was the reason behind the PHP session not being set.

    I still have no idea but it worked fine after this. I’ll have to research why this would cause a problem like this. If anyone knows why, please post the answer.

    I hope this helps someone. :-)

  4. Chris says:

    If anyone comes here because of CakePHP. Note that CakePHP locks the UserAgent in each session. The option

    Configure::write(‘Session.checkAgent’, false);

    should work around the problem.

  5. Mrik says:

    Edward, you are my savior. I had 2 domain names names on one website. Each time my users were using the second domain name I was losing the session on IE8 and not able to get it back without changing the session name on my app. With your setcookie and session_write_close that is not a problem anymore. A thousand of thanks to you !

  6. WebmasterPL says:

    Hi , your solution does not work :-( I have found this bug after years… damn Microsoft, damn IE, damn it.

    Here is my code

    if ( session_regenerate_id() /* sprawdzamy powodzenie operacji */ )
    {
    sleep(1);
    headers(‘302′); // by zmienic SSID
    location(‘/oplata.php?re=1&’. $_SERVER[“QUERY_STRING”]);
    exit;
    }

    I make regenerate to change session ID, then I redirect user to special site. And all browsers work OKAY but IE 8 does not ;-(

    It still sticks to old session id , I can see sess_…………… files on my server but IE holds to this old one like crazy.

    Your solution does not work :-( I need to keep session variables after redirect!

  7. Robb says:

    It seems that this problem STILL exists in IE 11 (!!!), a whole 6 YEARS after this blog post was published. Nice one microsoft.
    At first I replaced the – in my session_name with _ and that seemed to do the trick. Login works, everything works, nice, right? NOPE! Because IE. Two days later I check again and the problem is back. Now I incorporated your solution and it seems to work, but I’ll wait, before I cheer, don’t want to get disappointed for the millionth time by IE….

Leave a Reply to WebmasterPL