Skip to main content

Insecure or unset HTTP headers - Cache Control

Need

Implementation of secure and appropriate Cache Control headers

Context

  • Usage of Python 3.0+ for developing Python applications
  • Usage of Django for building web applications

Description

Non compliant code

from django.http import HttpResponse

def some_view(request):
response = HttpResponse()
# Here is the issue. The Cache-Control header is not set.
return response

In the code above, we are defining a Django view function some_view(). This function handles a HTTP request and returns a HTTP response.

The problem lies in the fact that the Cache-Control header is not set in the response. The Cache-Control HTTP header holds directives (instructions) for caching in both requests and responses. Not setting this header can lead to sensitive information being stored in the cache and hence potentially being exposed to unauthorized users.

In the context of security, the Cache-Control header is important because it allows the server to control who can cache a response, under which circumstances, and for how long. For instance, a server can specify that certain resources should not be cached, or that they should only be cached privately (i.e., by the client and not by intermediate caches), or that they are public resources that can be cached by anyone.

In this particular case, the absence of a Cache-Control header means that the server is not providing any caching directives to the client or any intermediate caches. This can potentially lead to sensitive information being cached in locations where it should not be, and hence being exposed to unauthorized users.

Steps

  • Identify the HttpResponse object where the Cache-Control header needs to be set.
  • Use the 'set' method of the HttpResponse object to set the Cache-Control header.
  • Set the Cache-Control header to 'no-store' or 'no-cache, no-store, must-revalidate' to prevent caching of sensitive information.
  • Ensure that the Cache-Control header is set for all responses that contain sensitive information.

Compliant code

from django.http import HttpResponse

def some_view(request):
response = HttpResponse()
# Set the Cache-Control header to 'no-store' to prevent caching of sensitive information.
response['Cache-Control'] = 'no-store'
return response

The original code was vulnerable because it did not set the Cache-Control HTTP header. This header is used to specify directives for caching mechanisms in both requests and responses. When not set or improperly configured, it can lead to sensitive information being stored in cache, which can be accessed by unauthorized users.

The fixed code sets the Cache-Control header to 'no-store' for the HttpResponse object. This directive tells the browser, and all intermediate caches, not to store any version of the returned response—for example, within the browser’s cache or a CDN. This is particularly important when dealing with sensitive information, as it ensures that once the user has finished with the data it will not be written to disk.

Remember, it's important to set the Cache-Control header for all responses that contain sensitive information to prevent potential data leaks.

References