Uncontrolled external site redirect - Java

Uncontrolled external site redirect - Java

Need

Controlled and secure external site redirection

Context

  • Usage of Java 8 for developing applications with enhanced features and performance improvements.
  • Usage of javax.servlet-api for developing Java web applications with Servlets

Description

Non compliant code

        import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RedirectServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String redirectURL = request.getParameter("redirectURL");
        response.sendRedirect(redirectURL);
    }
}
        
        

The above Java Servlet code is vulnerable to uncontrolled external site redirect. The doGet method reads a URL from the request's redirectURL parameter and then redirects the response to that URL.

The vulnerability lies in the fact that the application does not validate or control the redirectURL parameter. An attacker could manipulate the redirectURL parameter to point to a malicious website. When a user clicks on a manipulated link, they would be redirected to the attacker's site. This is a type of phishing attack and could lead to serious security breaches.

In this scenario, the attacker could craft a URL that includes the malicious redirect. For example: http://yourapp.com/redirect?redirectURL=http://malicious.com. When a user clicks on this link, the application would redirect them to http://malicious.com, thus exposing them to potential harm.

This vulnerability could be exploited to steal sensitive information or to distribute malware. It is a serious issue and should be fixed by implementing proper validation and control of the redirectURL parameter.

Steps

  • Validate and sanitize user input: Before using the redirectURL parameter, ensure that it is a valid and trusted URL. Use input validation techniques to check for any malicious or unexpected input.
  • Whitelist allowed URLs: Maintain a whitelist of trusted URLs that the application can redirect to. Validate the redirectURL parameter against this whitelist to ensure that only allowed URLs are redirected to.
  • Implement a secure redirect mechanism: Instead of directly using the redirectURL parameter in the response.sendRedirect() method, consider using a secure redirect mechanism that prevents open redirects. This can involve validating the URL, checking for any potential open redirect vulnerabilities, and constructing the redirect URL programmatically.
  • Implement a redirect confirmation page: If possible, implement a confirmation page before performing the redirect. This can help the user verify the redirect destination and prevent any unintended redirects.
  • Log and monitor redirect activities: Implement logging and monitoring mechanisms to track and analyze redirect activities. This can help detect any suspicious or malicious redirect attempts and enable timely response.
  • Regularly update and patch dependencies: Keep all relevant libraries and frameworks up to date to ensure that any known vulnerabilities related to redirects are addressed.
  • Educate developers: Provide training and awareness programs to developers about the risks and best practices related to uncontrolled external site redirects. This can help them write secure code and avoid introducing vulnerabilities.

Compliant code

        import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RedirectServlet extends HttpServlet {

    private static final List WHITELISTED_URLS = Arrays.asList("https://trustedurl1.com", "https://trustedurl2.com");

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String redirectURL = request.getParameter("redirectURL");

        if (isValidURL(redirectURL)) {
            response.sendRedirect(redirectURL);
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid or untrusted redirect URL");
        }
    }

    private boolean isValidURL(String url) {
        try {
            new URL(url); // Checks if the URL is valid
            return WHITELISTED_URLS.contains(url); // Checks if the URL is whitelisted
        } catch (MalformedURLException e) {
            return false;
        }
    }
}
        
        

The updated code includes a whitelist of trusted URLs that the application can redirect to. The doGet method now checks if the redirectURL parameter is a valid URL and if it is in the whitelist before performing the redirect. If the URL is not valid or not in the whitelist, the method sends an error response with the HTTP status code 400 (Bad Request) and a message indicating that the redirect URL is invalid or untrusted.

The isValidURL method is used to validate the redirectURL parameter. It first tries to create a new URL object with the redirectURL parameter. If the URL constructor does not throw a MalformedURLException, it means that the redirectURL parameter is a valid URL. The method then checks if the redirectURL parameter is in the WHITELISTED_URLS list. If it is, the method returns true; otherwise, it returns false.

This approach helps prevent uncontrolled external site redirects by ensuring that only valid and trusted URLs are used for redirects. It also provides a clear error message when an invalid or untrusted redirect URL is used, which can help with troubleshooting and error handling.

References