Skip to main content

Insecure or unset HTTP headers - Cache Control

Need

Prevent caching of sensitive data by client browsers and intermediate proxies

Context

  • Usage of Elixir (v1.11+) for building scalable and fault-tolerant applications
  • Usage of Plug for HTTP request and response handling

Description

Non compliant code

defmodule MyApp do
use Plug.Builder
def start_link(_) do
Plug.Adapters.Cowboy.http __MODULE__, []
end
plug :index
def index(conn, _opts) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
end
end

In this code, the application responds to every request with 'Hello, world!' but does not set any Cache-Control headers. This could lead to sensitive data being cached by the client browser or intermediate proxies.

Steps

  • Update the application to set appropriate Cache-Control headers on all responses. The specific value will depend on your application, but 'no-store, no-cache, must-revalidate' is a common secure value.

Compliant code

defmodule MyApp do
use Plug.Builder
def start_link(_) do
Plug.Adapters.Cowboy.http __MODULE__, []
end
plug :index
def index(conn, _opts) do
conn
|> put_resp_header("cache-control", "no-store, no-cache, must-revalidate")
|> put_resp_content_type("text/plain")
|> send_resp(200, "Hello, world!")
end
end

In this revised code, the application sets a Cache-Control header with the value 'no-store, no-cache, must-revalidate' on all responses. This instructs the client browser and any intermediate proxies not to store the response, thereby preventing the caching of sensitive data.

References