Content Security Policy (CSP) Implementation in Express.js

Content Security Policy (CSP) is a powerful security mechanism that helps prevent various web vulnerabilities, including Cross-Site Scripting (XSS), clickjacking, and code injection attacks. This chapter explains CSP implementation in Express.js, from understanding its purpose to advanced configuration techniques.

Introduction to Content Security Policy

What is CSP?

CSP is a security standard that allows you to specify which sources of content (scripts, styles, images, etc.) are allowed to load on a webpage. It acts as a whitelist for content, blocking unauthorized resources.

Why CSP is Important?

  1. Mitigates XSS: Prevents unauthorized scripts from executing.
  2. Prevents Data Injection: Restricts the inclusion of untrusted data sources.
  3. Improves Application Security: Blocks malicious content from loading.

How CSP Works

A CSP is delivered via an HTTP header (Content-Security-Policy) or a <meta> tag in HTML. The browser enforces the policy, blocking any content that doesn’t match the defined rules.

Key CSP Directives

  • default-src: Specifies the default content source for all types.
  • script-src: Controls the allowed sources for JavaScript.
  • style-src: Specifies allowed sources for CSS.
  • img-src: Restricts image sources.
  • connect-src: Defines permitted sources for AJAX or WebSocket connections.

Example CSP Header:

				
					Content-Security-Policy: default-src 'self'; script-src 'self' https://apis.google.com;

				
			

Introduction Implementing CSP in Express.js to Error Handling in Express.js

Setting CSP with Helmet.js

Helmet.js is a middleware package for securing Express apps. It includes built-in support for CSP.

Installation

				
					npm install helmet

				
			

Basic CSP Implementation

				
					const express = require('express');
const helmet = require('helmet');

const app = express();

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"], // Allow only content from the same origin
      scriptSrc: ["'self'", "https://trusted-scripts.com"], // Allow inline and trusted scripts
      styleSrc: ["'self'", "'unsafe-inline'"], // Allow inline styles
      imgSrc: ["'self'", "data:"], // Allow same-origin and base64-encoded images
      connectSrc: ["'self'", "https://api.example.com"], // Allow AJAX/WebSocket connections
    },
  })
);

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

app.listen(3000, () => console.log('Server running on http://localhost:3000'));

				
			

Explanation

  • defaultSrc: Sets the default source for all content types.
  • scriptSrc: Allows JavaScript from the current domain and specific external domains.
  • styleSrc: Permits inline styles ('unsafe-inline').
  • imgSrc: Limits images to same-origin or base64-encoded data.

Using Custom Middleware for CSP

You can also manually set the Content-Security-Policy header.

Example

				
					const express = require('express');

const app = express();

// Custom CSP middleware
app.use((req, res, next) => {
  res.setHeader(
    'Content-Security-Policy',
    "default-src 'self'; script-src 'self' https://trusted-cdn.com; img-src 'self' data:;"
  );
  next();
});

app.get('/', (req, res) => {
  res.send('<h1>Custom CSP Implementation</h1>');
});

app.listen(3000, () => console.log('Server running on http://localhost:3000'));

				
			

Explanation

  • Directly sets the header for every HTTP response.
  • Ensures fine-grained control over CSP directives.

Understanding CSP Violations

When a violation occurs, the browser blocks the resource and logs a message to the console. You can monitor violations using CSP reports.

Enabling CSP Reports

CSP can report violations to a specified endpoint using the report-uri or report-to directive.

Example

				
					app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"],
      reportUri: '/csp-violations', // Deprecated
      reportTo: 'csp-endpoint', // New standard
    },
    reportOnly: true, // Enable report-only mode for testing
  })
);

// Endpoint to log CSP violations
app.post('/csp-violations', express.json(), (req, res) => {
  console.log('CSP Violation:', req.body);
  res.sendStatus(204);
});

				
			

Explanation

  • reportUri: Specifies a URL where violation reports are sent (deprecated).
  • reportTo: Modern way to define reporting groups.
  • reportOnly: Allows testing the policy without blocking content

Advanced CSP Techniques

Using Nonces for Inline Scripts

Nonces are unique tokens generated for each request, allowing specific inline scripts to execute.

Example

				
					app.use((req, res, next) => {
  res.locals.nonce = 'unique-nonce-value'; // Generate a secure random value in production
  res.setHeader(
    'Content-Security-Policy',
    `script-src 'self' 'nonce-${res.locals.nonce}'`
  );
  next();
});

app.get('/', (req, res) => {
  res.send(` <script nonce="${res.locals.nonce}" type="litespeed/javascript">console.log('Safe inline script')</script> `);
});

				
			

Explanation

  • Nonces ensure only scripts with the correct nonce value execute, mitigating inline script vulnerabilities.

CSP in Multi-Page Applications

For large applications with different pages requiring distinct policies, dynamically generate CSP headers based on routes.

Example

				
					app.use((req, res, next) => {
  const cspDirectives = req.path === '/admin'
    ? "default-src 'self'; script-src 'self' https://admin-scripts.com;"
    : "default-src 'self'; script-src 'self';";

  res.setHeader('Content-Security-Policy', cspDirectives);
  next();
});

				
			

Testing and Debugging CSP

Browser DevTools

  • Open the browser console to view CSP violations.
  • Look for blocked resources or CSP errors.

Tools for CSP Testing

  • CSP Evaluator: Google’s tool for analyzing policies.
  • Report URI: Service to collect and analyze CSP violation reports.

Best Practices for CSP in Express.js

  • Start with Report-Only Mode: Test policies without blocking content initially.
  • Minimize 'unsafe-inline' and 'unsafe-eval': Avoid them to strengthen security.
  • Use Nonces or Hashes: For inline scripts and styles.
  • Monitor Violations: Analyze CSP reports to refine policies.
  • Use Helmet.js: Simplify CSP implementation with a modular approach.

Implementing a Content Security Policy (CSP) in Express.js is a critical step toward building secure web applications. By specifying trusted sources for scripts, styles, and other resources, CSP protects against common vulnerabilities like XSS and data injection attacks.Through the techniques and examples in this chapter, you’ve learned to implement CSP using Helmet.js, custom middleware, and advanced configurations. Adopting these practices ensures your applications are robust, resilient, and secure. Happy coding !❤️

Table of Contents

Contact here

Copyright © 2025 Diginode

Made with ❤️ in India