Skip to main content

Insecure or unset HTTP headers - Content-Type

Need

Enforce secure and properly set HTTP headers, including Content-Type.

Context

  • Usage of Java for building robust and scalable applications
  • Usage of javax.servlet for Java web application development
  • Usage of java.io for input and output operations in Java programming

Description

Non compliant code

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class VulnerableServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>Hello, World!</h1>");
out.println("</body></html>");
}
}

The above servlet code is vulnerable due to the absence of the Content-Type HTTP header in the server's response. When a client makes a GET request to this servlet, it responds with an HTML message. However, the servlet does not set the Content-Type header in the response.

The Content-Type HTTP header is used to indicate the media type of the resource. In responses, a Content-Type header tells the client what the content type of the returned content actually is.

Without the Content-Type header, the client has to guess what type of content it is receiving. This can lead to security vulnerabilities. For example, if an attacker can trick a browser into interpreting HTML content as JavaScript, they could potentially execute malicious scripts.

In this case, the client might misinterpret the HTML content as being of a different type, which could lead to various issues, including security vulnerabilities like Cross-Site Scripting (XSS).

Steps

  • Set the Content-Type header in the server responses.
  • Specify the appropriate MIME type for the content being returned.
  • Ensure that the Content-Type header is set before writing any response content.
  • Use a secure default Content-Type header if the specific content type is unknown.

Compliant code

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;

public class SecureServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html"); // Set the Content-Type header
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>Hello, World!</h1>");
out.println("</body></html>");
}
}

The above code fixes the vulnerability by setting the Content-Type header in the server responses. This is done using the setContentType method of the HttpServletResponse object. The argument to this method is a string specifying the MIME type of the content being returned. In this case, the content is HTML, so the MIME type is "text/html".

This change ensures that the Content-Type header is set before any response content is written. This is important because once the response content has been written, it's too late to set the header.

If the specific content type is unknown, a secure default Content-Type header should be used. For example, "application/octet-stream" could be used as a default. This would cause the browser to treat the response as a binary file, which would prevent any potentially malicious content from being executed.

By setting the Content-Type header, we can help protect against various types of attacks, such as Cross-Site Scripting (XSS) and MIME type confusion attacks.

References