Lack of data validation - Host Header Injection - Java

Lack of data validation - Host Header Injection - Java

Need

Implementation of proper input validation and sanitization to prevent host header injection

Context

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

Description

Non compliant code

        import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class VulnerableServlet extends javax.servlet.http.HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String server = request.getHeader("Host");
        response.sendRedirect("http://"+server+"/login");
    }
}
        
        

This code is a simple servlet that processes GET requests. The doGet method retrieves the Host header from the incoming HTTP request and uses it to form a URL for a redirect.

The vulnerability lies in the doGet method. It takes the value of the Host header from the incoming HTTP request and uses it directly to form a URL for a redirect. This is a problem because the Host header can be manipulated by an attacker.

An attacker can send a request with a malicious Host header. The application will then redirect the user to the malicious site. This could be used for phishing attacks, where the malicious site is designed to look like the original site and trick the user into entering their credentials.

This is a classic case of "Lack of data validation". The application is trusting user input (in this case, the Host header) without validating it. Any time you use user input in a sensitive operation like forming a URL for a redirect, you should validate the input to ensure it's safe to use.

Steps

  • Implement input validation on the 'Host' header to ensure it only contains valid values.
  • Use a whitelist approach to validate the 'Host' header against a list of trusted domains.
  • Sanitize the 'Host' header by removing any potentially malicious characters or patterns.
  • Implement proper error handling and logging to detect and mitigate any potential attacks.
  • Consider using a secure redirect mechanism that does not rely solely on the 'Host' header.

Compliant code

        import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

public class SecureServlet extends javax.servlet.http.HttpServlet {

    private static final List WHITELISTED_DOMAINS = Arrays.asList("example.com", "example2.com");

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String server = request.getHeader("Host");

        if (isValidDomain(server)) {
            response.sendRedirect("http://" + server + "/login");
        } else {
            response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid Host Header");
        }
    }

    private boolean isValidDomain(String domain) {
        return WHITELISTED_DOMAINS.contains(domain);
    }
}
        
        

The above code fixes the Host Header Injection vulnerability by implementing input validation on the 'Host' header.

The isValidDomain method checks if the 'Host' header value is in the list of whitelisted domains. If the domain is not in the whitelist, the method returns false, and the servlet responds with a 400 Bad Request error. This approach ensures that only trusted domains are allowed, effectively preventing Host Header Injection attacks.

The WHITELISTED_DOMAINS list contains the domains that are considered safe. This list should be updated according to your application's requirements.

This solution also implements proper error handling. If an attacker tries to manipulate the 'Host' header, the application will respond with an error, making it easier to detect and mitigate potential attacks.

Remember, it's always a good practice to use a secure redirect mechanism that does not rely solely on the 'Host' header. This code is a step in the right direction, but it's not a complete solution. Always consider other security measures in your application.

References