Open redirect vulnerability in javascript / jquery
I am trying to misinform my code to eliminate all Open Redirect vulnerabilities. For all my C # code, I have applied a hotfix to check if the URL provided by Response.Redirect is from the same domain as the application. If not, throw an exception.
The question I have is regarding open redirect instances in my .js code. The code marked as vulnerable is as follows:
window.open('Help/Admin/webhelp/' + helpFile, '_blank', 'toolbar=no, menubar=no, status=yes, scrollbars=yes, resizable=yes');
httpReqObject.open("GET", 'GetHelpLink.ashx?modid=' + _AdminHelpContext, true);
window.open('viewcontents.aspx?did=' + grid.rows[i].cells[gridCell.docID].innerText, "toobar=0,menubar=0,resizable=1")
What is the best way to fix this Open Redirect vulnerability in my javascript code?
Thank.
source to share
Here's what I found to solve this problem. I agree that this is not one of the most elegant solutions and may require some refinement, but it satisfies my basic requirement of not allowing the user to navigate to a URL that is outside the application domain:
function LaunchHelp(surl) {
try {
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('/')
};
}
I needed to validate the hostname as an empty string for a script where the relative path ("Help / Admin / webhelp /") is provided to the LaunchHelp method. In this case, parseURL returns an empty hostname. I stole the parseURL method from here .
Any suggestions / comments / questions are appreciated.
source to share