express-csp-header vs helmet-csp
Content Security Policy (CSP) Middleware
express-csp-headerhelmet-csp

Content Security Policy (CSP) Middleware

Content Security Policy (CSP) Middleware libraries in Node.js help developers implement CSP headers in their web applications to enhance security by preventing cross-site scripting (XSS) and other code injection attacks. These middleware packages allow developers to define a CSP policy, which is then applied to HTTP responses, instructing the browser on which resources are allowed to load. This helps mitigate the risk of malicious content being executed in the context of a web application. express-csp-header is a flexible and easy-to-use middleware for setting CSP headers in Express applications, while helmet-csp is a part of the Helmet security middleware suite, providing a more opinionated and feature-rich approach to CSP implementation.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
express-csp-header29,1792457.4 kB1a month agoWTFPL
helmet-csp010,66216.5 kB42 years agoMIT

Feature Comparison: express-csp-header vs helmet-csp

Integration

  • express-csp-header:

    express-csp-header integrates easily with Express applications, allowing you to set CSP headers with minimal configuration. It supports both middleware and route-level implementation, giving you flexibility in how you apply CSP policies.

  • helmet-csp:

    helmet-csp is designed to work as part of the Helmet middleware suite, which means it integrates well with other security headers provided by Helmet. This makes it a good choice for applications looking to implement multiple security headers in a cohesive manner.

Customization

  • express-csp-header:

    express-csp-header offers high customization for CSP policies, allowing you to define directives dynamically based on your application’s needs. You can easily adjust policies for specific routes or conditions, making it very flexible.

  • helmet-csp:

    helmet-csp provides a more structured approach to CSP customization, with predefined directives and a clear API for setting policies. While it is customizable, it encourages developers to follow best practices and use the provided structure.

Simplicity vs. Structure

  • express-csp-header:

    express-csp-header is simple and straightforward, making it easy to implement CSP without much complexity. Its lightweight nature means it won’t add significant overhead to your application.

  • helmet-csp:

    helmet-csp is more structured and opinionated, which can be beneficial for teams looking for a clear and consistent way to implement CSP. However, this structure may introduce a learning curve for those unfamiliar with Helmet.

Documentation and Community

  • express-csp-header:

    express-csp-header has clear documentation and an active community, making it easy for developers to understand and implement its features. Its simplicity and flexibility have made it popular among developers looking for a lightweight CSP solution.

  • helmet-csp:

    helmet-csp benefits from being part of the well-established Helmet suite, which has extensive documentation and a large community. This makes it a reliable choice for developers looking for a tried-and-true solution for security headers.

Ease of Use: Code Examples

  • express-csp-header:

    Setting CSP with express-csp-header

    const express = require('express');
    const { csp } = require('express-csp-header');
    
    const app = express();
    
    app.use(csp({
      defaultSrc: "'self'",
      scriptSrc: ["'self'", "https://trustedscripts.example.com"],
      styleSrc: ["'self'", "https://trustedstyles.example.com"],
    }));
    
    app.get('/', (req, res) => {
      res.send('CSP headers set!');
    });
    
    app.listen(3000, () => {
      console.log('Server running on http://localhost:3000');
    });
    
  • helmet-csp:

    Setting CSP with helmet-csp

    const express = require('express');
    const helmet = require('helmet');
    
    const app = express();
    
    app.use(helmet.csp({
      directives: {
        defaultSrc: ["'self'"],
        scriptSrc: ["'self'", "https://trustedscripts.example.com"],
        styleSrc: ["'self'", "https://trustedstyles.example.com"],
      },
    }));
    
    app.get('/', (req, res) => {
      res.send('CSP headers set with Helmet!');
    });
    
    app.listen(3000, () => {
      console.log('Server running on http://localhost:3000');
    });
    

How to Choose: express-csp-header vs helmet-csp

  • express-csp-header:

    Choose express-csp-header if you need a lightweight and flexible solution for setting CSP headers with fine-grained control over policies. It is ideal for applications that require custom CSP configurations without much overhead.

  • helmet-csp:

    Choose helmet-csp if you want a comprehensive security solution that integrates seamlessly with other Helmet middleware. It is suitable for applications that benefit from a more structured and opinionated approach to security headers, including CSP.

README for express-csp-header

Content-Security-Policy middleware for Express

NPM version NPM downloads Dependency Status

Middleware wrapper for csp-header, so for more information read its documentation.

Usage

const { expressCspHeader, INLINE, NONE, SELF } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'default-src': [SELF],
        'script-src': [SELF, INLINE, 'somehost.com'],
        'style-src': [SELF, 'mystyles.net'],
        'img-src': ['data:', 'images.com'],
        'worker-src': [NONE],
        'block-all-mixed-content': true
    }
}));

// express will send header "Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' somehost.com; style-src 'self' mystyles.net; img-src data: images.com; workers-src 'none'; block-all-mixed-content; report-uri https://cspreport.com/send;'

nonce parameter

If you want to use nonce parameter you should use NONCE constant. Nonce key will be generated automatically. Also generated nonce key will be stored in req.nonce:

const { expressCspHeader, NONCE } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'script-src': [NONCE]
    }
}));
// express will send header with a random nonce key "Content-Security-Policy: script-src 'nonce-pSQ9TwXOMI+HezKshnuRaw==';"

app.use((req, res) => {
    console.log(req.nonce); // 'pSQ9TwXOMI+HezKshnuRaw=='
})

Auto tld

If you have more than one tlds you may want to have only current tld in your security policy. You can do this by replacing tld by TLD constant:

const { expressCspHeader, TLD } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'script-src': [`mystatic.${TLD}`]
    }
}));
// for myhost.com it will send: "Content-Security-Policy: script-src mystatic.com;"
// for myhost.net it will send: "Content-Security-Policy: script-src mystatic.net;"
// etc

TLD parsing options

express-csp-header uses psl package to parse tld for auto-tld feature. If you have a custom tld you can specify it as an array or a regexp.

const { expressCspHeader, TLD } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'script-src': [`mystatic.${TLD}`]
    },
    domainOptions: {
        customTlds: ['example.com']
    }
}));
// for myhost.com it will send: "Content-Security-Policy: script-src mystatic.com;"
// for myhost.example.com it will send: "Content-Security-Policy: script-src mystatic.example.com;"
// etc

Custom processing

const { expressCspHeader } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'default-src': ["#someString#"],
        'script-src': ["#someOtherString#"],
    },
    processCspString: (cspString, req, res) => {
        // here you can process final cspString
        return cspString.replaceAll('#someString#', 'https://example.com').replaceAll('#someOtherString#', 'https://example2.com');
    }
}));

CSP violation report

For more information read csp-header documentation. express-csp-header helps you manage both Content-Security-Policy and Reporting-Endpoints headers. Report-to headers is no longer recommended to use

const { expressCspHeader, INLINE, NONE, SELF } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'default-src': [SELF],
        'report-to': 'csp-default'
    },
    reportUri: 'https://cspreport.com/send',
    reportingEndpoints: [
        {'csp-default': 'https://cspreport.com/send'}
    ]  
}));

/* express will send two headers
1. Content-Security-Policy: default-src 'self'; report-to csp-default; report-uri https://cspreport.com/send;
2. Reporting-Endpoints: csp-default="https://cspreport.com/send"
*/

Presets

Read about preset in csp-header docs

Content-Security-Policy-Report-Only mode

To switch on Report-Only mode just specify reportOnly param:

const { expressCspHeader, SELF } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'script-src': [SELF]
    },
    reportOnly: true
}));
// it will send: "Content-Security-Policy-Report-Only: script-src 'self';"

report-uri parameter

const { expressCspHeader, SELF } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'script-src': [SELF]
    },
    reportUri: 'https://cspreport.com/send'
}));
// express will send header "Content-Security-Policy: script-src 'self'; report-uri https://cspreport.com/send;"

If you want to pass some params to the report uri just pass function instead of string:

const { expressCspHeader, SELF } = require('express-csp-header');

app.use(expressCspHeader({
    directives: {
        'script-src': [SELF]
    },
    reportUri: (req, res) => {
        return `https://cspreport.com/send?time=${Number(new Date())}`;
    }
}));
// express will send header "Content-Security-Policy: script-src 'self'; report-uri https://cspreport.com/send?time=1460467355592;"

Links