Insecure or unset HTTP headers - Strict Transport Security - Java

Insecure or unset HTTP headers - Strict Transport Security - Java

Need

Enforcement of Strict Transport Security (HSTS) headers

Context

  • Usage of Java for building cross-platform applications
  • Usage of javax.servlet for building Java web applications with servlets
  • Usage of javax.servlet.http for handling HTTP requests and responses in Java web applications

Description

Non compliant code

        import javax.servlet.*;
import javax.servlet.http.*;

public class VulnerableServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("");
        out.println("

Hello World

"); out.println(""); } }

The above code is a simple servlet that responds to HTTP GET requests. It sets the content type of the response to "text/html" and writes a simple HTML document to the response's output stream.

The vulnerability here is that it does not set the Strict-Transport-Security HTTP header in the response. The Strict-Transport-Security header is a security feature that tells browsers to only communicate with the server using HTTPS, not HTTP. By not setting this header, the server is potentially vulnerable to man-in-the-middle attacks, where attackers can intercept and alter the communication between the server and the client.

Additionally, even if the Strict-Transport-Security header was set, if the max-age attribute of the header is set too short, it could also lead to potential security risks. The max-age attribute tells the browser how long to remember to only communicate with the server over HTTPS. If this is set too short, the browser could revert back to using HTTP after the max-age has expired, again potentially exposing the communication to man-in-the-middle attacks.

Steps

  • Implement HTTPS for the server
  • Set the Strict-Transport-Security HTTP header with an appropriate max-age value
  • Ensure that the Strict-Transport-Security header is included in the response for all HTTPS requests

Compliant code

        import javax.servlet.*;
import javax.servlet.http.*;

public class SecureServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        response.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
        PrintWriter out = response.getWriter();
        out.println("");
        out.println("

Hello World

"); out.println(""); } }

The above code is a fixed version of the original vulnerable servlet. The vulnerability was that the server was missing the Strict-Transport-Security HTTP header, or the header's max-age was too short. This could potentially allow for man-in-the-middle attacks.

The fix involves setting the Strict-Transport-Security HTTP header in the server's responses. This is done using the setHeader method of the HttpServletResponse object. The header is set to "Strict-Transport-Security", and the value is "max-age=31536000; includeSubDomains".

The max-age directive specifies the amount of time, in seconds, that the browser should remember that this site is only to be accessed using HTTPS. A value of 31536000 seconds is equivalent to one year, which is a common setting.

The includeSubDomains directive is an optional directive that, if specified, tells the browser that all subdomains of the current domain should also be accessed only over HTTPS.

This fix ensures that the server includes the Strict-Transport-Security header in the response for all HTTPS requests, thus mitigating the vulnerability.

References