Skip to main content

Insecure or unset HTTP headers - Cache Control

Need

Implementation of secure and appropriate Cache Control headers

Context

  • Usage of Scala for building scalable and high-performance applications
  • Usage of play.api.mvc for handling HTTP requests and responses in Play Framework
  • Usage of play.api.mvc.ControllerComponents for building controllers in Play Framework
  • Usage of play.api.mvc.BaseController for creating base controllers 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.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.Result for handling HTTP responses in Play Framework
  • Usage of play.api.mvc.Results.Ok for returning an HTTP 200 OK 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 code snippet is a simple controller in a Scala Play framework application. It has an index() function that responds to HTTP requests with a "Welcome to the Home Page!" message. However, this code is vulnerable due to the lack of a Cache-Control security header.

The Cache-Control HTTP header holds directives (instructions) for caching in both requests and responses. The lack of a Cache-Control header means that the application is not providing any instructions to the client or intermediate caches about how to cache the response. This might lead to sensitive information being stored in publicly accessible caches, which can be exploited by attackers to gain unauthorized access to this information.

In this particular example, the index() function sends a response without setting any Cache-Control directives. This means that the response could be cached by any cache that the response passes through before reaching the client. If this response includes sensitive information, it could be stored and later retrieved by an attacker.

Steps

  • Add the Cache-Control header to the response in the index() method.
  • Set the value of the Cache-Control header to a secure value, such as 'no-store, no-cache, must-revalidate'.
  • Ensure that the Cache-Control header is set for all responses in the application, not just the index() method.
  • Consider using a framework-specific configuration or middleware to automatically set the Cache-Control header for all responses.
  • Test the application to verify that the Cache-Control header is properly set and the vulnerability is resolved.

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(CACHE_CONTROL -> "no-store, no-cache, must-revalidate")
}
}

The original code was vulnerable due to the lack of a Cache-Control header in the HTTP response. This could potentially lead to sensitive information being stored in the cache and being accessible to unauthorized users.

The fixed code includes the Cache-Control header in the HTTP response of the index() method. The value of the Cache-Control header is set to 'no-store, no-cache, must-revalidate', which instructs the browser not to store the page in its cache. This means that the page will not be served from cache, but will be requested from the server every time, preventing sensitive information from being stored and accessed from the cache.

This fix only applies to the index() method. It is recommended to set the Cache-Control header for all responses in the application, not just the index() method. This can be achieved by using a framework-specific configuration or middleware to automatically set the Cache-Control header for all responses.

After applying the fix, it is important to test the application to verify that the Cache-Control header is properly set and the vulnerability is resolved.

References