Insecure or unset HTTP headers - Content-Type - PHP

Insecure or unset HTTP headers - Content-Type - PHP

Need

Enforcement of secure and properly defined Content-Type headers in server responses

Context

  • Usage of PHP for server-side scripting and web development
  • Usage of Response for handling HTTP responses

Description

Non compliant code

        public function getResponse()
{
    $response = new Response();
    $response->setContent('Hello World');
    return $response;
}
        
        

The above code represents a method in a Laravel controller, which returns a Response object with the content set as 'Hello World'. However, it does not set the Content-Type HTTP header.

The Content-Type HTTP header is important because it tells the client what the content type of the returned content actually is. Browsers will do MIME sniffing in some cases and will not always choose the right action to take if a Content-Type header is not specified.

If the Content-Type header is not set, the browser might interpret the received content differently than intended by the server. This could lead to security issues such as Cross-Site Scripting (XSS) attacks if the content includes user input.

In this case, the vulnerability lies in the fact that the application does not explicitly define the Content-Type header in the server responses, leaving it up to the client to guess the content type.

Steps

  • Identify where the response is being generated in your code.
  • Ensure that the Content-Type header is being set for every HTTP response.
  • Use the setHeader or addHeader method of the response object to set the Content-Type header.
  • The value of the Content-Type header should match the type of content that is being returned by the server.
  • Test your changes to ensure that the Content-Type header is being correctly set in all responses.

Compliant code

        public function getResponse()
{
    $response = new Response();
    $response->setContent('Hello World');
    $response->headers->set('Content-Type', 'text/plain');
    return $response;
}
        
        

The above code is a fixed version of the vulnerable code. The vulnerability was that the Content-Type header was not being set in the HTTP response. This can lead to security issues as it allows for potential MIME type confusion attacks.

In the fixed code, we have added a line that sets the Content-Type header for the HTTP response. The set method of the headers property of the Response object is used to set the Content-Type header. The first argument to the set method is the name of the header ('Content-Type') and the second argument is the value of the header ('text/plain').

This ensures that the Content-Type header is always set in the HTTP response, mitigating the vulnerability. The value of the Content-Type header should be changed to match the type of content that is being returned by the server.

After making these changes, it is important to test your application to ensure that the Content-Type header is being correctly set in all responses.

References