Insecure or unset HTTP headers - Content-Type - Scala

Insecure or unset HTTP headers - Content-Type - Scala

Need

Enforcement of secure and properly defined HTTP headers

Context

  • Usage of Scala for building scalable and high-performance applications
  • Usage of play.api.mvc for handling HTTP requests and building web applications in the Play framework

Description

Non compliant code

        import play.api.mvc._

object Application extends Controller {
  def index = Action {
    Ok("Hello World")
  }
}
        
        

The above code represents a basic HTTP endpoint in a Scala application using the Play framework. The endpoint responds to HTTP requests with a 200 OK response and a body of "Hello World".

However, this code is vulnerable because it does not define the Content-Type header in the server response. The Content-Type HTTP header is important because it tells the client what the content type of the returned content actually is.

Browsers use the Content-Type header to handle responses correctly. If this header is not set, the browser may incorrectly interpret the content, leading to potential security issues such as Cross-Site Scripting (XSS) attacks.

In this case, the server is sending a plain text response ("Hello World") without specifying that the content type is text. If an attacker can manipulate the response to include executable code (such as JavaScript), and the browser interprets the response as HTML (the default when no Content-Type is specified), the attacker's code could be executed in the user's browser.

Steps

  • Set the Content-Type header in the server responses.
  • Determine the appropriate Content-Type for the response data.
  • Use the `withHeaders` method to add the Content-Type header to the response.
  • Ensure that the Content-Type header is set correctly for different types of responses (e.g., JSON, HTML, XML).

Compliant code

        import play.api.mvc._

object Application extends Controller {
  def index = Action {
    Ok("Hello World").withHeaders(CONTENT_TYPE -> "text/plain")
  }
}
        
        

The above code fixes the vulnerability by setting the Content-Type header in the server responses. The withHeaders method is used to add the Content-Type header to the response. In this case, the Content-Type is set to "text/plain" because the response data is a plain text string "Hello World".

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 necessarily follow the value of this header; to prevent this behavior, the header X-Content-Type-Options can be set to nosniff.

In the context of security, incorrect or missing Content-Type header can lead to security issues such as Cross-Site Scripting (XSS) attacks. Therefore, it's crucial to always set the Content-Type header correctly.

Remember to adjust the Content-Type according to the type of data your application is returning. For example, if you're returning JSON data, the Content-Type should be set to "application/json". If you're returning HTML, the Content-Type should be set to "text/html", and so on.

References