Friday 24th June 2011

A Weird Redirect Behaviour in Firefox 5 and IE9

This is an interesting little "bug" which I've found in the first release of Firefox 5.0 Arguably it's a feature, as the RFC seems vague on what to do if this header isn't set. I suspect that some web application developers will be tripped up by this one.

It seems that Firefox 5 interprets certain types of redirect as cachable.

If the server sends a "Location:" header without a "Pragma: no-cache" header, then Firefox 5 will interpret this redirect as permanent and cacheable. The effect of this is that subsequent requests for the original URL won't actually be sent to that URL. Firefox will step in and simply request the previously redirected URL, without requesting the original URL at all.

The only way to get Firefox 5 to request the original URL is to clear the browser's history completely, and then request the original URL again.

This bug can manifest itself when an application redirects non-logged in users to a specific login URL, and then allow the user to view the originally requested URL once logged in. If the redirect occurs using a "Location:" header without a "Pragma: no-cache" header accompanying it, then the user will never subsequently be able to view the original requested URL. When the user clicks a link pointing to that URL, or types that URL into their browsers, Firefox will simply request the redirected login URL instead.

I wrote some proof of concept code in PHP to test this. There's a zip file of that code here. It consists of two index.php files in seperate paths. One (at document root level) tests for the presence for a session value, and redirects to a "login" page (at /redirect/index.php) if the session value is not set. This second URL allows the user to "login" and then return to the originally requested URL.

If the "Pragma: no-cache" value is not sent prior to the redirect, then Firefox 5 will not allow to the user to return to the original URL once "logged in"

Commenting out the following line in the /index.php file allows the "Pragma: no-cache" header to be set by PHP, at which point the problem goes away.

session_cache_limiter('private_no_expire');

I've also uploaded a couple of demos so users can test this:

  1. Pragma: no-cache no set - Firefox 5 should fail this test.
  2. Pragma: no-cache set - Firefox 5 should pass this test.
  3. Download the test code

 UPDATE: It seems that Internet Explorer 9 does exactly the same thing

The Solution:

Ok. I reported this in Bugzilla, and Mozilla have marked it as a won't fix. Their take on this is that our test code is sending an incorrect cache-control header.

Cache-Control: private, max-age=10800, pre-check=10800

The above header is telling Firefox that it can cache the redirect. It is being sent automatically by PHP in this case. What we need to to do is stop PHP from sending this header, and instead send:

Cache-Control: no-cache

If you're having similar problems with a location redirect in a PHP application, make sure that you are issuing the following header instruction at some point before the Location: header is sent. In fact, you probably want to be declaring the header at the top of your application to avoid similar caching problems elsewhere:

header("Cache-Control: no-cache");

Issuing the above should fix the problem altogether. This will probably also fix IE9 Location: redirect problems.

 

“ From the outset, invent Partners got the balance right and were prepared to listen to our needs, whilst at the same time offering their depth of knowledge and experience. The end product we received is exceptional and has since proven its worth, fundamentally from a ‘back end’ input and management information viewpoint and importantly from a ‘front end’ consumer ease of use stance. Needless to say, we are growing our business as a result, with 80% of web business as ‘net new’. ”
Ged, Vertigrow Ltd

Contact Us