Incorrect caching of HTTP 302 responses in Opera

Contents

Problem Description

This bug occured on <www.truecrypt.org> when redirecting a browser from an isolated <frame> page to its parent <frameset> page.

When the <frame> is requested from an outside location, (e.g. when the request comes with a Referer: header from another site), the server returns a 302 redirect to the frameset page. The frameset in turn links to the original URL, only this time, the Referer: header contains an expected location, so the server responds with an ordinary 200 response.

The problem is that Opera caches the first 302 response and sends the browser into infinite recursion.

The test case

I have simplified the original problem page, <http://www.truecrypt.org/docs/header-key-derivation>, into a small test case containing a frameset page [f0] with two frames [f1] and [f2].

When [f2] is requested with a Referer: that does not come from [f0], the server responds with a 302 redirection to [f0].

Analysis

Browser request:

Server response:

RFC 2616 has the following to say about 302 responses:

10.3.3 302 Found

The requested resource resides temporarily under a different URI. Since the redirection might be altered on occasion, the client SHOULD continue to use the Request-URI for future requests. This response is only cacheable if indicated by a Cache-Control or Expires header field.

So later, when the frame page is referenced from the frameset page, the browser should send a request for the original URL with the expected Referer: header. Like this:

Browser request (hypothetical):

Server response:

This is where Opera goes wrong. It never sends this request. Instead it re-uses the 302 response recieved earlier, and displays either an empty frame or a page thrown into recursion.