There are different types of attack exists in web programming like SQL Injection Attack, Cross Site Scripting Attack(XSS), Open Redirection Attack etc. and we need to take care of these attacks when writing code and try to prevent our application from these attack.
Today, we will talk about Open Redirection Attack and see the code which prevents it at server side level as well as client side level.
Web application works on http protocol and redirect to some URL when we click on any link or button. Some time we pass URL in query string and some time passes directly. But this URL can be changed by external users (hackers) and they can tampered these URL and redirect to some malicious URL that is called Open Redirection Attack.
As per CWE 601
Therefore, generally we forget to write code to prevent Open Redirection Attack. We just take the URL and redirect to it. However, this is not good way to redirect.
We need to check URL and identify that “is this malicious or not?” We need to do these things at code level.
Example of Open Redirection Attack
Let say, there is a website name as called “abc.com” which has one login page where user can pass their credentials to login in system. When user passes user name, password, and click to log in button, it redirects to some other page where credentials will validate and then it will redirect to welcome page.
However, hackers tampered redirect URL of welcome page with some malicious page, which look and feels will same as abc.com login page and there will show a message that “user name and password are incorrect”. Here generally nobody will care about URL and just retype their valid credentials and click to login. But this time user has entered their credentials with some malicious site and being hacked.
Server Side Prevention of Open Redirection Attack
So, prevent this type of scenario we need to write code to check URL which is processing by system, if anything goes wrong it just shows error page or redirect to login page. Generally we do redirection in Asp.Net as following.
if (!String.IsNullOrEmpty(returnUrl))
{
Response.Redirect(returnUrl);
}
else
{
Response.Redirect("login.aspx");
}
Here we are only checking Null and Empty of URL, we don’t have intension to check URL is valid or not. To check valid URL, we will validate Request. In the following code, we are validating HttpContext.Current.Request.
We can check the provided URL is local URL or not, local URL means which belongs to same domain. If URL looks that belongs to outside then it will show error page or redirect to login page.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace Helper
{
public class RequestExtensions
{
System.Web.HttpRequest request = HttpContext.Current.Request;
public bool IsLocalUrl(string url)
{
if (string.IsNullOrEmpty(url))
{
return false;
}
Uri absoluteUri;
if (Uri.TryCreate(url, UriKind.Absolute, out absoluteUri))
{
return String.Equals(request.Url.Host, absoluteUri.Host,
StringComparison.OrdinalIgnoreCase);
}
else
{
bool isLocal = !url.StartsWith("http:", StringComparison.OrdinalIgnoreCase)
&& !url.StartsWith("https:", StringComparison.OrdinalIgnoreCase)
&& Uri.IsWellFormedUriString(url, UriKind.Relative);
return isLocal;
}
}
}
}
And before redirecting to URL, we will check and validate. If everything is fine then we will redirect to provide URL otherwise redirect to login.aspx page. This will prevent to redirect your page to some other domain which might be not secure or might be tampered by third party users. So always be sure before making any redirection, just check the URL, does it exist locally or not.
Helper.RequestExtensions requestExtension = new RequestExtensions();
string returnUrl = Request.QueryString["redirectPage"];
if (requestExtension.IsLocalUrl(returnUrl))
{
Response.Redirect(returnUrl);
}
else
{
Response.Redirect("login.aspx");
}
Following code is validating returnURL exists locally or not.
Client Side Prevention of Open Redirection Attack
Following code is full example of how to check URL at client side and validate that this URL is belongs to same domain where system is running.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script>
function LaunchHelp() {
try {
var surl = "http://www.google.com";
if (validateURL(surl))
window.open(surl, '_blank', 'toolbar=no,menubar=no,status=yes');
else {
throw new InvalidURLException();
}
} catch (e) {
if (e instanceof InvalidURLException)
alert(e.message);
}
}
function InvalidURLException() {
this.message = "An attempt was made to open a webpage of foreign domain. No allowed.";
this.toString = function () {
return this.message
};
}
function validateURL(surl) {
var url = parseURL(surl);
var urlHostname = url.hostname.trim();
if (urlHostname == '') {
return true;
}
else {
if (urlHostname.toUpperCase() == location.hostname.trim().toUpperCase()) {
return true;
}
else
return false;
}
}
function parseURL(url) {
var a = document.createElement('a');
a.href = url;
return {
source: url,
protocol: a.protocol.replace(':', ''),
hostname: a.hostname,
host: a.host,
port: a.port,
query: a.search,
params: (function () {
var ret = {},
seg = a.search.replace(/^\?/, '').split('&'),
len = seg.length, i = 0, s;
for (; i < len; i++) {
if (!seg[i]) { continue; }
s = seg[i].split('=');
ret[s[0]] = s[1];
}
return ret;
})(),
file: (a.pathname.match(/\/([^\/?#]+)$/i) || [, ''])[1],
hash: a.hash.replace('#', ''),
path: a.pathname.replace(/^([^\/])/, '/$1'),
relative: (a.href.match(/tps?:\/\/[^\/]+(.+)/) || [, ''])[1],
segments: a.pathname.replace(/^\//, '').split('/')
};
}
</script>
</head>
<body>
<h1>This is Test 1 Page.</h1>
<button id="btnRedirect" name="btnRedirect" onclick="LaunchHelp()">Redirect</button>
</body>
</html>
Conclusion:
So, today we have learned how to prevent Open Redirection Attack at server side as well as client side.
I hope this post will help you. Please put your feedback using comment which helps me to improve myself for next post. If you have any doubts please ask your doubts or query in the comment section and If you like this post, please share it with your friends. Thanks
Posted Comments :
Deepak Posted : 4 Years Ago
I have used client side code for URL validation as you have mention above in article but it doesn't work for me. It is still showing me this Open redirection in Burp Suite scan. ----------------------------------------------------------------------------------------- Static analysis Data is read from location.pathname and passed to window.open() via the following statements:
Deepak Posted : 4 Years Ago
I have used client side code for URL validation as you have mention above in article but it doesn't work for me. It is still showing me this Open redirection in Burp Suite scan. ----------------------------------------------------------------------------------------- Static analysis Data is read from location.pathname and passed to window.open() via the following statements: