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.

+3


source to share


1 answer


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.

+3


source







All Articles