Vulnerable JavaScript function call

Claude :

I have the following JavaScipt function in my application, that redirects user to the login page after a minute:

(function redirect_expired() {
    $j.get('/app/ExpiredSession', function (resp) {
        if (resp && resp.redirectTo) {
            window.location.href = resp.redirectTo;
        }
    });
    setInterval(redirect_expired, 60 * 1000);
})();

and a related Java servlet function:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
    PrintWriter pw = resp.getWriter();
    resp.setContentType("application/json");
    if (req.getSession != null && req.getSession().getAttribute("authorizationBean") == null) {
        pw.print("{\"redirectTo\": \"" + req.getContentPath() + "\"}");
    } else {
        pw.print("{\"redirectTo\": \"\"}");
    }
    pw.close();
}

When I scan my application with Fortify, I got the following vulnerabilities in JavaScript function:

  • The method lambda() sends unvalidated data to a web browser on line window.location.href = resp.redirectTo;, which can result in the browser executing malicious code.
  • JS function passes unvalidated data to an HTTP redirect function on line window.location.href = resp.redirectTo;. Alloving unvalidated input to control the URL used in rredirect can aid phishing attacks.

Could someone please explain me what is actually wrong with this redirect call window.location.href = resp.redirectTo; and how I can fix it?

Maybe I can add some additional input check on Java side?

ButchMonkey :

JS function passes unvalidated data to an HTTP redirect function on line window.location.href = resp.redirectTo;Allowing unvalidated input to control the URL used in redirect can aid phishing attacks.

Your redirect is using the value back from your get. You have no way of being sure that the url you receive is the url that you are expecting. If your /app/ExpiredSession page were to be compromised, you might get back a malicious url.

In the case of the warning they suggest phishing attacks which could pose as another site, in the attempt to get a users credentials (for example). In your case, as you are redirecting to a different page, you could be subject to "Reverse Tabnabbing" where the malicious page could pose as your site and fool the user into believing that they never left your page.

There are different ways that you might want to validate that the url is trusted. A simple method would be to store a list of trusted urls or domains and check that you recognise the url before redirecting to it.

A more concrete method would be to use SSL pinning. Which will ensure that you only communicate with servers that you trust and over SSL (using https). This works by saving a fingerprint of the SSL certificate and comparing it against the target of the request. If they are different then we assume that the site is compromised and should not continue with the request.

A combination of the two would mean that you only communicate with trusted sites when making a request, and that you only redirect to sites that you "know" of.


JS function passes unvalidated data to an HTTP redirect function on line window.location.href = resp.redirectTo;. Allowing unvalidated input to control the URL used in redirect can aid phishing attacks.

It is possible to inject malicious code into the urls, which you can test by running

window.location.href = "javascript:alert(1)"

There are some good OWASP suggestions on how to validate urls

  • Input starting with a / to redirect to local pages is not safe. //example.org is a valid URL.
  • Input starting with the desired domain name is not safe. https://example.org.attacker.com is valid.
  • Only allow HTTP(S) protocols. All other protocols, including JavaScript URIs such as javascript:alert(1) should be blocked
  • Data URIs such as data:text/html,<script>alert(document.domain)</script> should be blocked
  • URIs containing CRLF characters can lead to header injection or response splitting attacks, and should be blocked

Here is an example using a regex for Javascript suggested by OWASP

var validateUrl = new RegExp(/^((((https?|ftps?|gopher|telnet|nntp):\/\/)|(mailto:|news:))(%[0-9A-Fa-f]{2}|[-()_.!~*';/?:@&=+$,A-Za-z0-9])+)([).!';/?:,][[:blank:|:blank:]])?$/)
var url = 'http://google.com' 
if (url.match(validateUrl)) {
    console.log('Redirecting to', url)
} else {
     // Do not do anything with the url variable here, executing it could be dangerous
    console.log('Not a valid url')
}

This regex will prevent against the above cases, except in the case of https://example.org.attacker.com. However, this case is resolved by using the above suggestion of having a list of trusted domains. You can see for yourself here

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=415980&siteId=1