0
0
ExpressHow-ToBeginner · 4 min read

How to Use Content Security Policy in Express for Secure Apps

To use Content Security Policy (CSP) in Express, install the helmet middleware and configure its contentSecurityPolicy option with your desired rules. Then add it as middleware in your Express app to set CSP headers that control which resources can load.
📐

Syntax

The basic syntax involves importing helmet and using its contentSecurityPolicy middleware in your Express app. You provide a directives object that defines allowed sources for scripts, styles, images, etc.

  • helmet(): Main security middleware that can enable many protections.
  • contentSecurityPolicy({ directives }): Middleware to set CSP headers with rules.
  • directives: Object specifying allowed sources like 'self', URLs, or 'none'.
javascript
import express from 'express';
import helmet from 'helmet';

const app = express();

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", 'trusted.com'],
      styleSrc: ["'self'", 'fonts.googleapis.com'],
      imgSrc: ["'self'", 'images.com'],
      connectSrc: ["'self'"],
      fontSrc: ["'self'", 'fonts.gstatic.com'],
      objectSrc: ["'none'"],
      upgradeInsecureRequests: [],
    },
  })
);

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

app.listen(3000);
💻

Example

This example shows a simple Express server using helmet to set a Content Security Policy that only allows scripts and styles from the same origin and trusted domains. It protects your app by blocking unauthorized resource loading.

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

const app = express();

app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", 'cdn.example.com'],
      styleSrc: ["'self'", 'cdn.example.com'],
      imgSrc: ["'self'"],
      objectSrc: ["'none'"],
      upgradeInsecureRequests: [],
    },
  })
);

app.get('/', (req, res) => {
  res.send('<h1>Content Security Policy is active!</h1>');
});

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

Common Pitfalls

Common mistakes when using CSP in Express include:

  • Not allowing needed sources, causing resources like scripts or styles to be blocked unexpectedly.
  • Forgetting to include 'self' in directives, which blocks your own domain's resources.
  • Using overly permissive rules like * or unsafe-inline which weaken security.
  • Not testing CSP headers in different browsers or environments.

Always tailor directives to your app's needs and test carefully.

javascript
/* Wrong: Allows unsafe inline scripts, weakening security */
app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'unsafe-inline'", "'self'"]
    }
  })
);

/* Right: Avoids unsafe-inline, uses hashes or nonces if inline scripts needed */
app.use(
  helmet.contentSecurityPolicy({
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'"]
    }
  })
);
📊

Quick Reference

Here is a quick summary of common CSP directives used with helmet.contentSecurityPolicy:

DirectivePurposeExample Values
defaultSrcFallback for all resource types'self', 'none', https://example.com
scriptSrcAllowed script sources'self', 'unsafe-inline', cdn.example.com
styleSrcAllowed style sources'self', 'unsafe-inline', fonts.googleapis.com
imgSrcAllowed image sources'self', data:, images.com
connectSrcAllowed AJAX, WebSocket connections'self', api.example.com
fontSrcAllowed font sources'self', fonts.gstatic.com
objectSrcAllowed plugin/object sources'none'
upgradeInsecureRequestsAutomatically upgrade HTTP to HTTPSEmpty array [] to enable

Key Takeaways

Use helmet's contentSecurityPolicy middleware to set CSP headers in Express.
Define clear directives to specify trusted sources for scripts, styles, images, and more.
Avoid unsafe directives like 'unsafe-inline' unless absolutely necessary.
Test your CSP rules to ensure your app resources load correctly without security gaps.
Include 'self' in directives to allow your own domain's resources.