Skip to main content

Insecure or unset HTTP headers - Cache Control

Need

Enforcement of secure and appropriate Cache Control headers

Context

  • Usage of PHP 7.0+ for server-side scripting and web development
  • Usage of Illuminate/Http for HTTP request handling in Laravel
  • Usage of illuminate/view for rendering views in the Illuminate framework

Description

Non compliant code

<?php

namespace App\\Http\\Controllers;

use Illuminate\\Http\\Request;

class VulnerableController extends Controller
{
public function index()
{
$response = response()->view('welcome');
return $response;
}
}

In the above code snippet, a basic Laravel controller is defined. This controller has a single method index(), which is responsible for handling HTTP requests to the application's root URL.

The index() method creates a response object by calling response()->view('welcome'), which generates a view of the welcome page and wraps it in a response object. Then, it returns this response object.

The problem here is that the response object does not set the Cache-Control HTTP header. This is a security vulnerability because the Cache-Control header is used to prevent sensitive application data from being stored in the cache of the user's browser or intermediate proxies. If sensitive data is cached, it could potentially be accessed by unauthorized users.

Without the Cache-Control header, the application relies on the default behavior of the user's browser or intermediate proxies for caching, which may not always align with the security needs of the application.

Steps

  • Identify where the HTTP response is being generated in your code. In this case, it's in the 'index' method of the 'VulnerableController' class.
  • Add the 'Cache-Control' header to the HTTP response. This can be done using the 'header' method on the response object.
  • Set the 'Cache-Control' header to a secure value. This typically includes 'no-store, no-cache, must-revalidate, max-age=0'. This will instruct the client not to store a cached copy of the response.
  • Ensure that the 'Cache-Control' header is set for all HTTP responses, not just in the identified location. This might involve refactoring your code to ensure the header is set in a central location.

Compliant code

<?php

namespace App\\Http\\Controllers;

use Illuminate\\Http\\Request;

class SecureController extends Controller
{
public function index()
{
$response = response()->view('welcome');
$response->header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0');
return $response;
}
}

The above code fixes the vulnerability by adding the 'Cache-Control' HTTP header to the response object. This is done in the 'index' method of the 'SecureController' class.

The 'Cache-Control' header is set to 'no-store, no-cache, must-revalidate, max-age=0'. This instructs the client not to store a cached copy of the response. This is a secure setting for the 'Cache-Control' header that helps to prevent sensitive information from being stored in the cache.

The 'header' method on the response object is used to add the 'Cache-Control' header. This method takes two arguments: the name of the header and the value of the header.

It's important to note that the 'Cache-Control' header should be set for all HTTP responses, not just in the identified location. This might involve refactoring your code to ensure the header is set in a central location. This will help to ensure that all responses from your application are secure.

References