npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

netlify-plugin-csp-generator

v1.6.1

Published

Generate CSP headers from inline script hashes

Downloads

545

Readme

netlify-plugin-csp-generator

NPM codecov CodeQL

Generate Content-Security-Policy headers from inline script and style hashes

When running things like Gatsby or Gridsome, the initial state is stored inside a <script> tag. Modern browser content security policies don't like inline scripts or styles, so to get around it you need to add either a cryptographic nonce or a cryptographic hash of each script. A nonce is out of the question, because you can't update it for each load.

This package generates a crypographic hash (SHA-256) of all inline scripts and styles in each HTML file, and adds it to the _headers file along with other policies of your choice.

Note
Netlify lets you add a Content-Security-Policy header in your netlify.toml. This will overwrite values inside _headers, so don't do that.

If you have an existing _headers file, this will append to the existing file. Just make sure the file ends on a newline, and it should work fine.

Usage

Install netlify-plugin-csp-generator with your favourite package manager:

yarn add netlify-plugin-csp-generator

npm install netlify-plugin-csp-generator

In your netlify.toml file, add an additional plugin:

[[plugins]]
package = "netlify-plugin-csp-generator"

  [plugins.inputs]
  buildDir = "dist"

  [plugins.inputs.policies]
    defaultSrc = "'self'"

Properties

  • buildDir is the path for the publish directory in Netlify: buildDir example
  • exclude is an array of paths you don't want to include. It defaults to an empty array. See Excluding files and folders for more information.
  • disablePolicies is an array of policies to never include. Files that need these rules will probably be taken from defaultSrc instead by your browser.
  • disableGeneratedPolicies is an array of policies never to generate. Use this to turn off default policies but still allow the key in netlify.toml.
  • reportOnly generates headers with Content-Security-Policy-Report-Only instead, which is useful for testing.
  • reportURI/reportTo sends violations to a given endpoint. See Reporting violations for more information.
  • generateForAllFiles lets you generate headers for non-HTML files. See Non-index.html files for more information.
  • debug is a boolean that logs the file paths if set to true. Use this if you are struggling to match paths in your app.

Policies

You can use the following policies:

Add them under the [plugins.inputs.policies] object in your netlify.toml file, with your specified value in quotes.

You can use CSP headers not in this list too - simply use the name in camel case and it will be added.

Inline styles

When using Vue and derivatives (like Gridsome), you may want to use v-show on things. This adds an inline style of display: none;, which is forbidden by CSP Level 3. To prevent this throwing an error, you need to add 'unsafe-hashes' to your styleSrc policy. The sha-256 hash is generated automatically.

[[plugins]]
package = "netlify-plugin-csp-generator"

  [plugins.inputs]
  buildDir = "dist"

  [plugins.inputs.policies]
    defaultSrc = "'self'"
    styleSrc = "'unsafe-hashes'"

What is generated

If you have defined a policy in your netlify.toml file, this will be added to all files.

  [plugins.inputs.policies]
    defaultSrc = "'self'"
    scriptSrc = "'self' https://www.google-analytics.com https://ssl.google-analytics.com https://www.googletagmanager.com"
/each-file-path/
  Content-Security-Policy: default-src 'self'; script-src 'self' *.google-analytics.com;

If a file includes a <script> or <style> tag with content, this file path will have the hash added:

/file-with-no-script/
  Content-Security-Policy: default-src 'self';
/file-with-script/
  Content-Security-Policy: default-src 'self'; script-src 'sha256-RFWPLDbv2BY+rCkDzsE+0fr8ylGr2R2faWMhq4lfEQc=';

If a file has any inline styles, these will be hashed:

<div style="display:none;"></div>
/file-with-inline-style/
  Content-Security-Policy: style-src 'unsafe-hashes' 'sha256-0EZqoz+oBhx7gF4nvY2bSqoGyy4zLjNF+SDQXGp/ZrY='

Excluding files and folders

If you want to exclude any files or folders from being included, add them to the exclude array. Wildcard matching is provided by globby, which enables advanced pattern matching.

[[plugins]]
package = "netlify-plugin-csp-generator"

  [plugins.inputs]
  buildDir = "dist"
  exclude = ["/exclude-file.html", "/exclude-folder/**"]

Non-index.html files

Generally, routes are generated with an index.html file, like /some/file/path/index.html. However, sometimes you need to handle HTML files that aren't called 'index', for example 404.html in Nuxt.

These are generated as wildcard links and are placed above the non-wildcard paths in your _headers file (for specificity):

/*.html
  Content-Security-Policy: default-src 'self'; script-src 'sha256-Qb2XxXiF09k6xbk2vTgHvWRed+mgYYGzFqZ6dShQVA0=';
/specific-path/
  Content-Security-Policy: default-src 'self';

Any matching wildcard URL has the hashes joined together - for example, if you have a 404.html and a 500.html with scripts/styles, all the hashes will be merged together under /*.html.

In general, it is better to generate /path/index.html rather than /path.html.

Using the generateForAllFiles setting, you can generate route keys that use /* instead of /*.html. Be careful, this will send Content-Security-Policy headers for every file type (i.e. .js, .css, etc) which is redundant as per the spec.

Reporting violations

The Content-Security-Policy specification allows for reporting violations to a URL - you can read more about it on MDN.

This is useful for testing and checking directives.

To set the header to report only, set reportOnly = true in your netlify.toml alongside your policies.

  [plugins.inputs]
  reportOnly = true
  reportURI = "/report-csp-violations-to-this-uri"

Important

  1. Setting reportOnly to true will NOT enforce your policy
  2. You need to add reportURI too

Using the report-to directive

The reportURI is deprecated in CSP Level 3 in favour of report-to. To use the report-to directive, set the reportTo value to the group name as defined in the Reporting-Endpoints header that you also need to set.

  [plugins.inputs]
  reportOnly = true
  reportTo = "csp-violations-group"
  1. You can include reportURI and reportTo without setting reportOnly = true, and the policy WILL be enforced and errors will also be reported
  2. You can set both the reportTo and reportURI directives - this is recommended to ensure maximum compatibility

Help it's all broken!

Oh, you. Chances are your browser console is screaming at you, and the network tab is showing a lot of (blocked:csp) errors.

See our list of example policies to get started.

Don't unsafe-inline everything, because that will make CSP redundant. If in doubt, ask Google, Stackoverflow, or create a Github issue (in that order).

Donations

If you found this plugin useful, or are just feeling nice, feel free to donate!

Buy me a coffee