Hacking Sites with Unvalidated Redirects And Forwards
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.
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.