Case study – Open Redirect

Most of us are familiar with the ‘Open Redirect’ vulnerability; an OWASP top 10 vulnerability that takes advantage of a situation in which the application receives a parameter from the client and uses it to build the URL location to which the user is redirected, without performing sufficient validation on the received input.

Typically, attackers can exploit vulnerable applications in order to perform phishing attacks, redirecting the victims to phishing sites that look exactly (or partially) like the vulnerable application. The victims tend to believe they are still in the original website, and provide their credentials in order to perform the required login. Unfortunately, these credentials are sent directly to the attacker.

A Classic Open Redirect Scenario

The following image demonstrates a vulnerable website (victim-site.com), which is vulnerable to the common open redirect scenario; a login page that will redirect the user to the page specified in the ‘returnURL’ parameter after successful login (the rectangle outlines the URL of the index page):

Screenshot_1

In the following code snippet, we can see the outlined vulnerable code, which receives the redirect page from the client, in the ‘returnURL’ parameter, and set it directly to the “Location” header:

Screenshot_2

The following image shows the client request and response from the server. It is possible to see that the ‘returnURL’ parameter value in the request, is then used in the “Location” header in the response:

Screenshot_3

 

Exploit the Vulnerability

An attacker can exploit this vulnerability in order to redirect the victim to malicious phishing website, simply by sending him the following URL: http://victim-site.com/login.php?returnUrl=http://attacker-site.com

(To obfuscate the phishing site, the attacker can use:
%68%74%74%70%3a%2f%2f%61%74%74%61%63%6b%65%72%2d%73%69%74%65%2e%63%6f%6d, which is a URL encoded version of the website).

The phishing website will mislead the victim and lure him to inserting his credentials again and sending them directly to the attacker.

Test ccenario – a Bad solution

In many occasions, the solution to prevent open redirect attacks is against best practice does not completely mitigate the problem.

The following code snippet image outlined the wrong mitigation for open redirect vulnerability that I came across in several applications:

Screenshot_4

The developer assumed that since the application contains a prefixed string set in the Location header, malicious attackers will not be able to affect the redirected domain. This point of view is actually quite logical at first impression, and as such – this is what happened when trying to exploit it:

Screenshot_5

We can see that the Location header is redirecting to a non-valid address which includes both the prefix domain and the parameter sent in the returnURL parameter. Therefore, we get:

Screenshot_6

 

So… why is it a bad solution?

If we simply add a dingle dot (.) before we add the phishing website, we will make the prefixed domain a subdomain for our phishing address. So, by sending the phishing URL (%2F is a URL encoding for a dot): http://victim-site.com/login.php?returnUrl=%2Fattacker-site.com

The result Location address would be: http://victim-site.com.attacker-site.com and the attacker will only need to create his phishing site under the subdomain victim-site.com instead of www.

Here we can see the server response, containing the prefixed domain as a subdomain to the phishing website, in the Location header:

Screenshot_7

And the successful redirection to the attacker’s phishing site:

Screenshot_8

 

Mitigation

There are a few ways to avoid open redirect attacks:

  1. The first and preferred solutions is to redirect based on index or UID instead of an actual link. For example, use redirection based on an internal mapping table:

{1:”http://victim-site.com/index.php”, 2:”http://victim-site.com/help.php”, 3:”http://victim-site.com/contact.php“, … }

In the server, accept only URLs that contain IDs of an existing index in the mapping table. For example:
https://victim-site.com/login.php?redirectURL=1

  1. Another way is to perform input validation in the server, on the received address. For example, using the following Regex:

^https:\/\/([a-z0-9]+\.){0,2}victim-site\.com\/.*$

  1. If you still prefer to use a prefixed string, remember to add the “/” at the end of it: http://victim-site.com/ to avoid being served as a sub-domain.
0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *