In this post, I describe two potential pitfalls with handling session cookies in Google Chrome and Internet Explorer while developing websites, and how to avoid them. The problem in Google Chrome relates to its handling of local/internal hostnames, and the problem in Internet Explorer relates to its privacy settings and compact privacy policies.
Today I spent some time cross-browser testing a PHP app. I do all my basic testing in Firefox, as that's my browser of choice, but of course sites have to be tested in other browsers before live rollout. Normally this doesn't cause any problems, except for the usual complaints about Internet Explorer's (lack of) standards compliance, but this time I ran into a couple of problems with session management.
As you'll probably be aware (since you're reading this article), sessions are a handy way of keeping track of user information across different pages. A common use case, and the one that inspired this article, is checking whether a user is logged in, and displaying content accordingly.
Sample PHP code to set a session cookie
In keeping with best practice, I usually initialise sessions like so:
$https = false;
if(isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] != 'off') $https = true;
$dirname = rtrim(dirname($_SERVER['PHP_SELF']), '/').'/';
session_set_cookie_params(0, $dirname, $_SERVER['HTTP_HOST'], $https, true);
These settings ensure that sessions are tracked via cookies rather than
Google Chrome session cookie problem
The first problem I discovered was the
$_SERVER['HTTP_HOST'] part. For simplicity's sake, I carry out my testing by running a web server and browser on the same machine, via localhost, hence
$_SERVER['HTTP_HOST'] evaluates to
localhost. Fine? I thought so, and so did Firefox. Unfortunately, Chromium didn't agree. The session wasn't started in Chromium, and I couldn't log in to the app. Thankfully the fix was fairly straightforward.
When testing a local site in Chromium, you must either access it via IP address (e.g. 127.0.0.1) or set the cookie domain parameter to the empty string.
Easy enough to do, if annoying. On to the next problem...
Internet Explorer session cookie problem
As I mentioned earlier, I'd also been having problems with Internet Explorer during my testing. Unfortunately, as my dev system runs Linux, to test with IE I had to use a Windows VM install, and therefore I was accessing the site via IP address rather than localhost. Consequently, it was clear that this was due to a different problem. When I searched the internet, it seemed that most people experiencing similar problems were using test domains that use an underscore _ character in them, in violation of RFC 1035. Since (a) I know this isn't allowed, and (b) I wasn't using a domain name at all, I knew this wasn't the cause of the problem. Some other people suggested client/server timezone differences as a possible cause. Again, this wasn't the case with my app. The root cause actually turned out to be related to privacy settings, but when I did stumble across the correct answer I didn't immediately realise it was correct.
When testing in Internet Explorer, either make sure that the privacy setting for your test site is Medium High or lower, OR set a P3P header in your code.
header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');