Educational write-up by Amit Klein: "A Refreshing Look at Redirection"
A Refreshing Look at Redirection
Amit Klein, November 2006
Introduction
============
In this short educational piece, I want to draw the reader's
attention to a fourth way of performing redirection, and its
importance. This isn't a new material, but apparently a lot of
people are not familiar with it.
The three ways of redirection
=============================
OK, everybody knows the three ways of redirection:
- Via 3xx response (in the Location HTTP response header)
- Via Javascript (or any other client side code) in the response
page (e.g. document.location=...)
- Via "META REFRESH"
(<meta http-equiv="Refresh" content="0; url=...">)
But is that all?
No; or as someone old and wise once said: "there is another
Skywalker".
The fourth way of redirection
=============================
Let's take a closer look at the third redirection method above.
What does it actually mean? Well, from the W3C HTML 4.01
specification (http://www.w3.org/TR/html401/struct/global.html#h-
7.4.4), I quote:
META and HTTP headers
The http-equiv attribute can be used in place of the name
attribute and has a special significance when documents are
retrieved via the Hypertext Transfer Protocol (HTTP). HTTP
servers may use the property name specified by the http-
equiv attribute to create an [RFC822]-style header in the
HTTP response. Please see the HTTP specification
([RFC2616]) for details on valid HTTP headers.
In other words, by writing
<meta http-equiv="Refresh" content="0; url=...">
We instruct the browser to virtually parse the equivalent of the
following HTTP response header:
Refresh: 0; url=...
And the obvious question is - what is this response header? To
answer that, we need to dig in the dusty archives. Apparently,
the Refresh header was invented by Netscape, in their "AN
EXPLORATION OF DYNAMIC DOCUMENTS" paper
(http://wp.netscape.com/assist/net_sites/pushpull.html). The
document is un-dated, but it references Netscape Navigator 1.1,
which was released in March 1995 according to Wikipedia
(http://en.wikipedia.org/wiki/Netscape_Navigator). This makes me
believe that the paper actually pre-dated the first HTTP 1.0
specification (RFC 1945, dated May 1996), and somehow never made
it to any of the HTTP RFCs (e.g. Roy T. Fielding post "Re:
HTTP/1.1 Refresh header field comments"
http://www.hpl.hp.com/personal/ange/archives/archives-96/http-wg-
archive/1657.html). Nevertheless, since the Refresh header was
de-facto standard in Navigator, Microsoft Explorer simply had to
support it (and from personal experience, IE 6.0 indeed supports
the Refresh header).
To summarize: yes, there's an HTTP response header by the name of
Refresh, and while it's not standard (RFC-wise), it is supported
by both Mozilla/FireFox, and Internet Explorer. And in fact, the
META REFRESH redirection is its derivative (and not vice versa).
Why should I care?
==================
Because you're a security professional, that's why! ;-)
Seriously, this has some interesting security implications. For a
start, if a Refresh header is used in an application to redirect
the user to a URL, which is constructed (insecurely) from user
input, then the application may in fact be vulnerable to HTTP
Response Splitting
(http://www.packetstormsecurity.org/papers/general/whitepaper_htt
presponse.pdf) or simply to HTTP response header injection or
maybe to open redirection. It follows that black box auditing is
better be aware of this header and detect situations wherein user
data can be injected to it. But even more importantly, static
analysis and source code searching should incorporate Refresh
header patterns.
Just as an example, the PhpBB HTTP Response Splitting
vulnerability discovered back in 2004 by Ory Segal
(http://www.securityfocus.com/archive/1/369405) was actually
based on injection into a Refresh response header, as you can
clearly see in the advisory.
Furthermore, the Refresh header may come in handy when you
discover an HTTP response header injection in a 2xx response
(maybe in a different HTTP response header, e.g. Set-Cookie or
Content-Type), but you can't "break out" of the HTTP response
header section and make it a full fledged HTTP response splitting
attack. This may be in a situation where some kind of anti HTTP
response splitting measure is in effect (something similar to
PHP's protection scheme; note though that PHP's protection scheme
is imperfect - see the discussion in my "HTTP Response Smuggling"
paper, http://www.securityfocus.com/archive/1/425593).
Now that you have the Refresh header in your arsenal, you can
still squeeze in an attack (albeit a weaker one), such as
redirecting the user to another URL (may be useful for phishing).
Personal note
=============
Notice my new email (same mailbox name, different mail provider).