Skip to main content

Insecure or unset HTTP headers - Strict Transport Security

Need

Enforce strict transport security by setting the appropriate HTTP headers

Context

  • Usage of Scala for building scalable and high-performance applications
  • Usage of play.api.mvc for handling HTTP requests and responses in the Play Framework
  • Usage of play.api.mvc.ControllerComponents for handling HTTP requests and managing controllers in Play Framework
  • Usage of play.api.mvc.BaseController for creating base controllers in Play Framework
  • Usage of play.api.mvc.Action for handling HTTP requests in Play Framework
  • Usage of play.api.mvc.Request for handling HTTP requests in Play Framework
  • Usage of play.api.mvc.AnyContent for handling any type of content in Play Framework
  • Usage of play.api.mvc.Request for handling HTTP requests in Play Framework
  • Usage of play.api.mvc.Ok for sending a successful HTTP response in Play Framework

Description

Non compliant code

import play.api.mvc._

class HomeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
def index() = Action { implicit request: Request[AnyContent] =>
Ok("Welcome to the home page!")
}
}

The above Scala code snippet is a basic Play Framework controller. It has a single action, index, which returns a simple text response "Welcome to the home page!".

The vulnerability lies in the fact that the response does not set the Strict-Transport-Security HTTP header. The Strict-Transport-Security header is an important security feature that tells browsers to only communicate with the server using HTTPS, even if the user attempts to access the site using HTTP. This helps to prevent man-in-the-middle attacks.

In addition, even if the header was set, if the max-age directive is too short, it may not provide adequate protection. The max-age directive specifies the number of seconds that the browser should remember that this site is only to be accessed using HTTPS.

Without the Strict-Transport-Security header, or with a too short max-age, the server is vulnerable to attacks where the attacker can intercept and alter the communication between the user and the server.

Steps

  • Add the Strict-Transport-Security HTTP header to the response
  • Set the max-age directive of the header to an appropriate value
  • Ensure that the header is only sent over secure connections (HTTPS)

Compliant code

import play.api.mvc._

class HomeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController {
def index() = Action { implicit request: Request[AnyContent] =>
Ok("Welcome to the home page!").withHeaders("Strict-Transport-Security" -> "max-age=31536000; includeSubDomains")
}
}

The above code fixes the vulnerability by adding the Strict-Transport-Security HTTP header to the response. This header is used to enforce the use of HTTPS and reduce the risk of man-in-the-middle attacks.

The max-age directive is set to 31536000, which is equivalent to one year. This means that the browser should remember that this site is only to be accessed using HTTPS for the next year.

The includeSubDomains directive is also included, which means that the rule applies to all subdomains as well.

Please note that the Strict-Transport-Security header should only be set over secure (HTTPS) connections. If it's set over a HTTP connection, it will be ignored by the browser. Therefore, make sure your application is served over HTTPS.

This change ensures that your server is no longer missing the Strict-Transport-Security HTTP header and that the max-age is set to an appropriate value, thus fixing the vulnerability.

References