Implementation of proper input validation and sanitization to prevent host header injection
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.
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.