How to Implement Content Security Policy (CSP) in an Express.js App

 

How to Implement Content Security Policy (CSP) in an Express.js App

Introduction

Content Security Policy (CSP) is a powerful security featur
e that helps protect your web app from cross-site scripting (XSS), clickjacking, and other code injection attacks. It works by allowing you to specify which sources of content (scripts, styles, images, etc.) are allowed to load and execute on your web page.

In this article, we'll learn how to set up a CSP header in an Express.js application.


What is CSP?

CSP is an HTTP header (Content-Security-Policy) that instructs the browser to restrict the sources of various resources like JavaScript, CSS, images, fonts, and more.

For example, you can tell the browser to only execute scripts loaded from your own domain and trusted CDNs, preventing malicious scripts from running.


Setting Up CSP in Express.js

Step 1: Create a Simple Express App

First, create a basic Express server if you don't have one already:

const express = require('express'); const app = express(); app.get('/', (req, res) => { res.send(` <h1>Welcome to CSP Demo</h1> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> `); }); app.listen(3000, () => console.log('Server started on http://localhost:3000'));

Step 2: Add CSP Header Manually

You can set headers in Express using middleware. Add a middleware to set the Content-Security-Policy header for all responses:

app.use((req, res, next) => { res.setHeader( 'Content-Security-Policy', "default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; style-src 'self' https://cdn.jsdelivr.net" ); next(); });
  • default-src 'self' means all content (images, frames, fonts, etc.) defaults to only loading from your domain.

  • script-src allows scripts only from your domain and jsdelivr CDN.

  • style-src allows styles from your domain and jsdelivr CDN.


Step 3: Test Your Setup

Run your server:

node app.js

Visit http://localhost:3000 in your browser.

Open the developer console and check under the Network tab → Response Headers for Content-Security-Policy.

Try adding an inline script in your HTML and see it blocked:

<script> alert('This will be blocked by CSP'); </script>

You should see a CSP violation in the browser console.


Using Helmet for Easier CSP Management

Instead of manually setting headers, you can use the Helmet middleware, which helps manage security headers, including CSP.

Install Helmet:

npm install helmet

Use it in your Express app:

const helmet = require('helmet'); app.use( helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", "https://cdn.jsdelivr.net"], styleSrc: ["'self'", "https://cdn.jsdelivr.net"], // Add other directives as needed }, }) );

Helmet will set the CSP header for you and also handle browser compatibility.


Summary

  • CSP helps prevent XSS and other attacks by controlling where resources can be loaded from.

  • In Express.js, you can set the Content-Security-Policy header manually or use Helmet for easier management.

  • Always specify trusted domains explicitly.

  • Avoid 'unsafe-inline' or 'unsafe-eval' whenever possible to keep your CSP strong.

Comments