URL Redirection – Attack and Defense
URL Redirection is a vulnerability which allows an attacker to force users of your application to an untrusted external site. The attack is most often performed by delivering a link to the victim, who then clicks the link and is unknowingly redirected to the malicious website.
This vulnerability exploits the inherent trust that a user has in the legitimate domain. Since the victim is generally unaware of URL redirections; they are considerably more susceptible to phishing and social engineering attacks.
URL Redirection in Penetration Testing
For penetration testers, most instances of URL redirection will be fairly obvious. A smaller number, on the other hand, are a little more complex. Below are three common types of URL redirection pentesters should look out for.
Type 1 – Parameter Based URL Redirection
Parameter based URL redirection is the most common and easy to spot. There are two behaviors which contribute to this issue:
- A GET parameter containing a URL/URI.
- A 302/301 redirect made using that parameter.
So if you see a parameter passed in a URL before a page redirection, it’s a good idea to test if that can be modified with an arbitrary URL.
Type 2 – Session Restoration URL Redirection (2 step)
Ever click a link within an application, only to find out your session has terminated? Many applications will give the courtesy of preserving the last URL they viewed, and redirect them to that location after they authenticate. This feature is useful, but is commonly the source of URL Redirection vulnerabilities.
The above URL brings us to the login page, and instructs the server to store
/dashboard to redirect the user after authentication. This scenario can be tricky since the application does not immediately reflect the URL in a 302 redirect, but is stored and waiting for a successful authorization.
When we authentication the server redirects us back to our dashboard.
But as a penetration tester we should always test the following:
Now this brings us to the login page. After we authenticate, the server redirects us to the external site:
Not super exciting, but don’t worry, we can take this one step further.
URL Redirection with Cross-site Scripting (XSS)
Type 3 – DOM Based URL Redirection
https://example.com/#dashboard, does not send
#dashboard to the application. In fact, you can verify this with Burp:
window.location.hash. We can confirm this with the browser console:
// use substr() to remove the '#' window.location = window.location.hash.substr(1)
This would be open redirection. An attacker could create a link
https://example.com/#https://www.virtuesecurity.com and phish example users! By using DOM attributes, this vulnerability may even be missed by pentesters who are only looking at Burp traffic.
URL Redirection Remediation
The vast majority of URL redirection vulnerabilities that we identify are generally considered “needless”. By needless, we mean these are redirects that only point to a small number of pages within an application. So if you don’t need to redirect users to a large number of external websites, you can probably change the scheme in which you redirect users to pages.
Mitigation Method 1: Whitelist URLs
If you don’t need to take the redirect via a query parameter then don’t take it. Instead, query your URLs by simpler numeric identifiers:
https://example.com/redirect?externalPage=1 https://example.com/redirect?externalPage=2 https://example.com/redirect?externalPage=3
If you are only redirecting users internally, use a page naming scheme:
https://example.com/redirect?page=dashboard https://example.com/redirect?page=account https://example.com/redirect?page=settings
Method 2: Regex
You may be inclined to use regex to validate URL parameters, however, extreme caution should be used here. Recently during a penetration test a client had implemented the following logic:
redirect_url = urlparse.urlparse(url) if bool(re.search("^https://example.com", url)): # Vulnerable code #redirect user else: # fail
Can you spot the vulnerability?
The following bypass could be used by an attacker:
To use regex it’s critical to use a trailing slash to prevent malicious use of subdomains:
redirect_url = urlparse.urlparse(url) if bool(re.search("^https://example.com/", url)): #redirect user else: # fail
Mitigation Method 3: The unavoidable arbitrary URL
For applications where whitelisting is simply not feasible, we recommend at minimum filtering based on protocol handler. A regex such as
^https?:// can ensure you redirect only to websites (and not
If your application is a secure authenticated application it is recommended that a “speed bump” is put in place. This would show a warning on screen that users are leaving to an external URL.
In conclusion, URL Redirection is not inherently bad, but you must take steps to ensure that users are both aware of external redirections that occur, and to minimize the locations where you redirect to when necessary to do so.