Thursday, November 23, 2006

Not all redirection scripts are created equal.

Now, I'm sure we're all used to redirection scripts by now, and most of us should be aware of the danger of HTTP Response Splitting when allowing user content in the headers we send, and that there is also a patch in PHP since 4.4.2 and 5.1.2 which prevents this by dissalowing multiple lines in a single header call. This patch is not completely bullet proof as articles such as HTTP Response Smuggling illustrate, but sometimes there's an easier way to achieve what you want.

First of all, what is it that HTTP Response splitting gets most used for anyway? XSS. So any injection that will give us an XSS vector is just as good as any other.

But like the title says, not all redirection scripts are created equal. The most common approach used to redirect people is somewhat similar to the following:

header ("Location: ".$_GET['url']);

Which, when the PHP patch is applied, should be perfectly safe when ti comes to preventing XSS.

But is that the only approach? As some recent auditing I've done has shown me, its not.

I found something like the following not too long ago:

header ('refresh: 0; URL="'.$_GET['url'].'"');

And while it may serve the same needs as the above it, its surprisingly different. But before I explain the exact problem, does the header look familiar to you? It should, its the header that is used in meta tags to redirect users, and if you've done much reading on XSS you should know that meta redirects are another way to execute javascript.

And unsurprisingly enough, the above header follows the same rules. The refresh header, unlike the location header allows you to redirect users to javascript: or other URLS, depending on what your browsers support, so it should be no trouble at all to simply pass a javascript url to the script and have the user execute the javascript.

Just goes to show how there is generally more than one way to do something, but going down an untested road will often lead to unforseen problems that have already been solved for other approaches.

No comments: