Skip to main content

Insecure or unset HTTP headers - Cache Control

Need

Implementation of secure and appropriate Cache Control HTTP headers

Context

  • Usage of TypeScript for statically typed JavaScript development
  • Usage of Express for building web applications and handling HTTP requests

Description

Non compliant code

import express from 'express';

const app = express();

app.get('/', (req, res) => {
res.send('Hello World');
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The vulnerability in this code is the lack of setting the Cache Control security header in the server response. This means that the response from the server can be cached by the browser, potentially storing sensitive information. Additionally, it opens up the possibility of cache poisoning attacks, where an attacker can manipulate the cached response to produce harmful server responses.

To fix this vulnerability, the Cache Control header should be set in the server response using a secure value such as "no-store", "no-cache", or "must-revalidate". This will ensure that the browser does not cache the server response or only caches it after revalidating with the server.

Steps

  • Import the 'helmet' package
  • Add the 'helmet' middleware to the Express app
  • Set the 'Cache-Control' header to a secure value in the 'helmet' middleware configuration

Compliant code

import express from 'express';
import helmet from 'helmet';

const app = express();

app.use(helmet({
contentSecurityPolicy: false,
frameguard: false,
dnsPrefetchControl: false,
hidePoweredBy: false,
hsts: false,
ieNoOpen: false,
noSniff: false,
xssFilter: false,
expectCt: false,
referrerPolicy: false,
featurePolicy: false,
permittedCrossDomainPolicies: false,
hpkp: false,
noCache: true // Add this line to set the Cache-Control header to no-cache
}));

app.get('/', (req, res) => {
res.send('Hello World');
});

app.listen(3000, () => {
console.log('Server is running on port 3000');
});

The fixed code addresses the vulnerability by setting the Cache-Control header to "no-cache" using the noCache option provided by the helmet middleware.

First, the code imports the express and helmet libraries. express is a popular web application framework for Node.js, and helmet is a middleware that helps secure Express applications by setting various HTTP headers.

Next, an instance of the Express application is created using express().

The helmet middleware is then applied to the application using app.use(helmet()). By default, helmet sets several security headers, but in this code, some of the headers are explicitly disabled by setting them to false. This is done to ensure that only the necessary headers are set and to avoid any conflicts with other security measures in the application.

To address the vulnerability, the noCache option is set to true. This instructs the helmet middleware to set the Cache-Control header to "no-cache" in the server responses. This prevents the browser from caching the server responses, ensuring that sensitive information is not stored in the cache.

Finally, a route handler is defined for the root path ("/") that sends the response "Hello World" when a request is made to that path.

The application is then set to listen on port 3000, and a message is logged to indicate that the server is running.

Overall, the fixed code uses the helmet middleware with the noCache option to set the Cache-Control header to "no-cache" and prevent caching of sensitive server responses.

References