Even in this day and age where a different company seems to be hacked almost daily, many systems still blindly trust user-supplied data when performing actions instead of validating the information. This post demonstrates how unvalidated redirects and forwards work and how they can be used for phishing and other security bypasses.

Unvalidated Redirects and Forwards

Websites often have functionality in place to automatically redirect or forward a user to a specific URL to improve the overall user experience. A common case is when a user is logged out of a system because their session has expired but it remembers what page they were on so the user can be returned back to where they where when they log back in. This helps the user to carry on seamlessly with what they were doing, while also securing their account.

Typically, a website will remember the page the user was on by storing it in the URL of the login page:

https://example.com/login.php?redirect=http://example.com/admin/dashboard

The URL to where the user will be redirected when they log in is stored as part of the query parameter redirect. Note that the query parameter name is arbitrary and could be called redirect, forward, url or something obscure like just the letter f to work. The server-side code will redirect the user to whatever URL is passed in as the redirect when the user logs in:

// authentication
if (valid_username_and_password($username, $password)) {

	// get the redirect URL
	$redirect_url = $_GET['redirect'];

	// redirect the user
	header("Location: " . $redirect_url);
}

In normal circumstances, the user would be redirected to a specific page that the system has put in as the redirect URL and the user experience is good.

Malicious Redirect URL

An attacker can exploit this by sending a user a link in an email, a text message, a tweet or other media so they are redirected to an arbitrary website:

https://example.com/login.php?redirect=https://evil.com/phishing.html

When the user clicks on this and logs in, they will be redirected to evil.com and may not notice that they have been redirected to a different website. The evil website would usually be styled to look exactly the same as the real website to increase the likeliness of phishing attacks.

To avoid detection when phishing, the attacker would also set up a website on a domain name very similar to the real domain name. For example, many bots have been written to try to phish gamers on steamcommunity.com by sharing pictures, images and links on sites with lookalike domains.

Some of the many registered lookalike domains for steamcommunity.com

Combined with open redirects, these phishing attacks are much more successful.

Domain Redirects In The Wild

In 2015 Shopify used the following URL to preview themes:

https://app.shopify.com/services/google/themes/preview/supply--blue?domain_name=some.domain.com

The URL would usually be the domain name to preview the theme but the link could be shared, tweeted or messaged with any value and an unsuspecting user would be redirected to any domain. Shopify thanked the hacker that found this vulnerability, @blinkms, with a $500 reward.

Similarly, an open redirect discovered in Google Maps allowed URLs such as:

https://maps.app.goo.gl/?link=https%3A%2F%2Fexample.org

This would redirect a user to the URL-encoded link https://example.com. However, in this case, the maps.app.goo.gl domain was only intended to be used internally at Google. This is particularly interesting because many automated tools that scan for malicious links trust the internal Google domains and do not flag them as suspicious.

Path Redirects

To mitigate the issue, many companies have opted to only include the URL path in the redirect, rather than the whole URL:

https://example.com/login.php?redirect=/admin/dashboard

In this case, the server appends the value "/admin/dashboard" to its own domain name "example.com" to redirect to https://example.com/admin/dashboard.

It would appear that anything inserted as the redirect value would only ever redirect to a page on the domain example.com so the risk of phishing is eliminated.

However, an attacker can still redirect the user away from the intended domain by sharing the link:

https://example.com/login.php?redirect=.attacker.com

This link would redirect to https://example.com.attacker.com - which is a perfectly valid domain name - but would no longer be under the control of the domain owners of example.com.

Unfortunately for Shopify, this was another vulnerability they had when a user would log in during the checkout process:

*.myshopify.com/account/login?checkout_url=.attacker.com

The researcher that discovered this vulnerability was also rewarded with $500 for pointing this out to Shopify.

Miscellaneous Redirects

Sometimes having unvalidated redirects is not the fault of the programmer at a company but the fault of a shared library used all across the internet.

A vulnerability in popular node.js middleware serve-static caused companies like LinkedIn and Yahoo! to redirect to any website with specially crafted URLs:

https://touch.www.linkedin.com////google.com/%2e%2e
developer.yahoo.com////mmdrd.com/%2e%2e
publish.yahoo.com////mmdrd.com/%2e%2e

This was an issue in the underlying piece of software commonly used across thousands of websites at the time. This meant that attackers would share links to sites that appeared to reputable companies but instead redirected out to a potentially malicious website.

Severity

Having redirects in websites like the above do not immediately cause security issues by themselves. However, they abuse the trust between a user and a website by redirecting the user without their knowledge to a different domain name, which can then be leveraged for other attacks.

The Open Web Application Security Project categorises these redirects as a "moderate" security risk:

Such redirects may attempt to install malware or trick victims into disclosing passwords or other sensitive information. Unsafe forwards may allow access control bypass.

However, Google does not consider open redirects to be a vulnerability that is severe enough to pay bug bounty hunters to report but they do note:

Of course, some improperly designed redirectors can lead to more serious flaws, and we often see it used to trigger the following vulnerabilities:

- Content Security Policy bypass
- Referrer check bypass
- URL whitelist bypass
- Angular ng-include bypass
- Working redirect to javascript: or data: URL

So it is clear that this vulnerability can be exploited to pivot towards other, more damaging attacks.

Remediations

The easiest remedy would be to not have open redirects at all. However, if they are to be used, all user input should be sanitised before being used in any server-side logic. The general rule is to be extremely paranoid about any values coming from the client that can affect how a program functions.