Skip to main content

Insecure or unset HTTP headers - Content-Security-Policy

Need

Implementation of secure and properly configured Content-Security-Policy 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('<h1>Hello, World!</h1>');
});

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

The vulnerability in this code is that it does not set the Content-Security-Policy header in the server response. This header is used to define a policy that specifies which content can be loaded by the browser and from where.

Without setting this header, the browser will not have any restrictions on loading content from potentially malicious sources. This can lead to various security issues such as embedding content, scripts, blobs, or images from these sources. It can also enable attacks like Cross-Site Scripting (XSS) and Cross-Site Leaks.

To fix this vulnerability, the code should include the Content-Security-Policy header in the server response and configure it in a secure way.

Steps

  • Install the helmet package: npm install helmet
  • Import the helmet package: import helmet from 'helmet';
  • Add the helmet middleware to the Express app: app.use(helmet());
  • Set the Content-Security-Policy header in the helmet middleware options: app.use(helmet({ contentSecurityPolicy: { directives: { defaultSrc: ['self'] } } }));
  • Remove the line res.send('<h1>Hello, World!</h1>'); as it is not relevant to fixing the vulnerability
  • Restart the server and test the application to ensure the Content-Security-Policy header is set correctly

Compliant code

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

const app = express();

app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ['self']
}
}
}));

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

The fixed code addresses the vulnerability related to insecure or unset HTTP headers, specifically the Content-Security-Policy header.

The code imports the necessary modules, 'express' and 'helmet', to create and configure an Express application.

The 'app' variable is assigned to the express() function, which creates a new Express application.

The 'helmet' middleware is then used to enhance the security of the application. The 'contentSecurityPolicy' option is passed to the 'helmet' middleware, which allows us to configure the Content-Security-Policy header.

Inside the 'directives' object, the 'defaultSrc' directive is set to ['self'], which means that the application allows content to be loaded only from the same origin.

Finally, the application listens on port 3000, and a message is logged to the console indicating that the server is running.

By setting the Content-Security-Policy header and configuring it securely, the fixed code mitigates the vulnerability by preventing the embedding of content, scripts, blobs, or images from potentially malicious sources. It also helps to prevent attacks like Cross-Site Scripting (XSS) and Cross-Site Leaks.

References