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.

 

“ Just wanted to send a quick 'thank you' to the Invent Partners team for all your help and support. I love the design of our new site and really appreciate the great service you provided at every stage - you turned a daunting project into one that I really enjoyed! Thanks again. ”
Lou, Advanced Writing Solutions

Contact Us