Open Redirects - what's the problem?

Been getting this question a bit lately. First off, what's an open redirect? It's a function in your application which sends the user to some other location. The redirect could be a response from the server, such as an HTTP 301 or 302 response code, or a META redirect. The redirect can be delivered in several forms, the important part is that when an attacker can control the redirect location, they can exploit it for nefarious purposes - usually this means spam or phishing attacks.

For example, your application takes a request from the user, maybe it's a GET request for a certain page. Included in the request is a value indicating the location where the user should be redirected once they've finished on the page. So, the user requests a page like:

http://somesite.tld/page.aspx?name=value&returnUrl=http://somesite.tld/referringpage.aspx

As you can see, the returnUrl takes a value of the redirect location. Then your code acts on it somewhere by redirecting the user with something like:

Response.Redirect(returnUrl);


Spammers and phishers love this, it gives them good camouflage. For example:

http://somesite.tld/page.aspx?name=value&returnUrl=http://evil.tld/installMalware.bad

Now imagine the spammer has crafted up a nice email that looks like it originates from somesite.tld, includes all the logos, fonts, etc. They coerce the victim into clicking this link by saying something like "your account needs immediate attention" or "you've won 500 points". User clicks the link, gets redirected to evil.tld, and may not realize that the domain has switched before they say Yes to install the thing that the spammer wants them to download.

Tricky, right. In fact this is a favorite of spam, malware, and phish, next to the old XSS bug.

What's the solution
Well, simply, don't redirect openly, rather, implement a SafeRedirect() function that looks something like:


public static SafeRedirect(string url) {
// check that protocol is either http:// https:// ftp:// or other specific protos you want to allow
// check that domain is in fact yourdomain.tld
// If these checks pass, then you can go ahead
Response.Redirect(returnUrl);
// If the checks fail, you can try to clean up the URL, but probably best to just fail and redirect to a safe landing page
}

That's about all there is too it.