slackhq / csp-html-webpack-plugin Goto Github PK
View Code? Open in Web Editor NEWA plugin which, when combined with HTMLWebpackPlugin, adds CSP tags to the HTML output.
License: MIT License
A plugin which, when combined with HTMLWebpackPlugin, adds CSP tags to the HTML output.
License: MIT License
Hey folks, can you please make some example that will show how to make this thingy working with CRA + react-app-rewired? Because all my attempts failed with no result in resulting index.html
I tried rewired function like that with no avail tho. I tried a few other approaches, also no result.
function addCspHtmlWebpackPlugin(config, env) {
config.plugins[0].options.cspPlugin = {
enabled: true,
policy: {
'base-uri': "'self'",
'script-src': ["'unsafe-inline'", "'self'"],
},
hashEnabled: {
'script-src': true,
},
nonceEnabled: {
'script-src': true,
},
}
config.plugins.push(
new CspHtmlWebpackPlugin(
{
'base-uri': "'self'",
'script-src': ["'unsafe-inline'", "'self'"],
},
{ ...config.plugins[0].options },
),
)
return config
}
I'm talking about this thing :)
https://github.com/timarney/react-app-rewired
Thanks!
x
in one of the [ ]
)x
in each of the [ ]
)Does this plugin not support yarn 2? With 5.1.0:
ERROR in TypeError: val.includes is not a function
- plugin.js:297
[csp-html-webpack-plugin-npm-5.1.0-40d465e733-0e41f2e490.zip]/[csp-html-web pack-plugin]/plugin.js:297:17
- Array.map
- plugin.js:290 CspHtmlWebpackPlugin.buildPolicy
[csp-html-webpack-plugin-npm-5.1.0-40d465e733-0e41f2e490.zip]/[csp-html-web pack-plugin]/plugin.js:290:8
- plugin.js:334 CspHtmlWebpackPlugin.processCsp
[csp-html-webpack-plugin-npm-5.1.0-40d465e733-0e41f2e490.zip]/[csp-html-web pack-plugin]/plugin.js:334:30
- new Promise
- index.js:348
[html-webpack-plugin-npm-5.0.0-beta.1-fd77fa0afb-d71b4e4a7b.zip]/[html-webp ack-plugin]/index.js:348:72
webpack 5.17.0 compiled with 2 errors in 4589 ms
I'll try cooking up a minimal repro later.
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version:
node version:
OS version(s):
What you expected to happen
What actually happened
Logs, screenshots, screencast, sample project, funny gif, etc.
According to Mozilla's documentation, CSP3 allows for the <hash-algorithm>-<base64-value>
attribute of script-src
to be applied for external scripts.
As I understand it (based on reading #35 and trying out the plugin myself), hashes are not generated and included for external scripts, only inline scripts.
It'd be nice if they could be included for external scripts too. (Maybe via a default-false
configuration option?)
The current package.json doesn't specify webpack 5 as a peer dependency. Is this intentional?
x
in one of the [ ]
)x
in each of the [ ]
)The CspHtmlWebpackPlugin is a plugin made for Webpack, but doesn't integrate with the Angular build process anymore. Since Angular 8+ will generate the index.html
outside the Webpack build process. You need to use the indexTransform
parameter of @angular-builders/custom-webpack to do this.
I wrote the code to do this. This code is already being used in production. But I think that it would be nicer when this code is incorporated into this project, so maintaining and testing is more easier.
You can find an example project on https://gitlab.flusso.nl/public-projects/angular-csp-html-transform-example.
I like to help / code this solution, but would like a direction how to do this.
x
in one of the [ ]
)x
in each of the [ ]
)When I use a custom processFn to procces the built policy, nonces aren't set in HTML elements. It works fine when I remove my custom processFn from additional Options
x
in one of the [ ]
)slackhq/csp-html-webpack-plugin version: 4.0.0
Here is my code:
const cspConfigPolicy = {
"default-src": ["'self'"],
"connect-src": [
"'self'",
REACT_APP_WS_BASE_URL,
REACT_APP_API_BASE_URL + "/",
REACT_APP_FIREBASE_REMOTE_CONFIG_PROXY_HOST,
REACT_APP_DATADOG_LOGS_PROXY_HOST,
REACT_APP_DATADOG_RUM_PROXY_HOST,
...REACT_APP_ALLOWED_CONNECT_SRC_URLS.split(","),
"https://firebaseinstallations.googleapis.com",
"https://fcmregistrations.googleapis.com",
"https://sentry.io",
"https://www.google-analytics.com/",
],
"base-uri": "'self'",
"script-src": [
"'self'",
"https://www.google.com/recaptcha/",
"https://use.fontawesome.com",
"https://www.googletagmanager.com",
"https://static.hotjar.com",
"https://storage.googleapis.com/workbox-cdn/",
"https://www.gstatic.com/",
"'unsafe-inline'",
...REACT_APP_ALLOWED_SCRIPT_SRC_URLS.split(","),
],
"style-src-elem": [
"'self'",
"'unsafe-inline'",
"https://fonts.googleapis.com/css",
],
"frame-src": [
"'self'",
"https://www.google.com/recaptcha/",
...REACT_APP_ALLOWED_FRAME_SRC_URLS.split(","),
],
"font-src": ["'self'", "https://fonts.gstatic.com/"],
"img-src": ["'self'", "data:"],
};
/**
* Used to write the built csp in a file in the build directory
* @param {string} builtPolicy
*/
const processBuiltCsp = (builtPolicy) => {
fs.writeFile("./build/csp.txt", builtPolicy, (err) => {
if (err) {
return;
}
});
};
function addCspHtmlWebpackPlugin(config) {
if (NODE_ENV === "production" && REACT_APP_CSP_ENABLE === "1") {
config.plugins.push(
new cspHtmlWebpackPlugin(cspConfigPolicy, {
processFn: processBuiltCsp,
})
);
}
return config;
}
During testing and fine-tuning it is helpful to add CSP in report-only mode. It would be helpful to have an additional option that would allow to not just enable/disable the CSP but to change it to Content-Security-Policy-Report-Only
x
in one of the [ ]
)x
in each of the [ ]
)The hash is wrong when the index.html EOL is CRLF
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 5.1.0
node version: v16.15.1
OS version(s): Windows 10
The hash is generated correctly.
The hash is wrong for CRLF index.html
When using React, Ant Design, webpack and Less - loader this plugin almost works out of the box. The only thing that does not seem to work is adding nonces to the inline styles in the element. Is their a way that you now of to get this to work?
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 5.1.0
node version: 12.18.3
OS version(s): Windows 10
const { override, fixBabelImports, addLessLoader } = require("customize-cra");
const cspHtmlWebpackPlugin = require("csp-html-webpack-plugin");
const path = require("path");
const cspConfigPolicy = {
"default-src": "'none'",
"base-uri": "'self'",
"object-src": "'none'",
"script-src": ["'self'"],
"frame-src": [],
"manifest-src": ["'self'"],
"font-src": ["'self'"],
"connect-src": [
"'self'",
],
"style-src": ["'self'", "'unsafe-inline'"],
"img-src": [
"'self'",
],
};
function addCspHtmlWebpackPlugin(config) {
config.plugins.push(new cspHtmlWebpackPlugin(cspConfigPolicy));
return config;
}
module.exports = override(
fixBabelImports("import", {
libraryName: "antd",
libraryDirectory: "es",
style: true,
}),
addLessLoader({
lessOptions: {
javascriptEnabled: true,
modifyVars: {
"ant-theme-file":
"; @import '" +
path.resolve(
__dirname,
"./src/shared-components/styles/vendors-extensions/antd.less"
) +
"'",
},
},
}),
addCspHtmlWebpackPlugin
);
To have a nonce attribute added, same way they are added to script-tags.
To have nonces also added to the inline script tags
Logs, screenshots, screencast, sample project, funny gif, etc.
Hi :) I got notified of 3.0.0 by dependabot in one of my repositories.
Dependabot was unable to show me the changelog and commits. I noticed that the link to the repository was https://github.com/anuj/csp-html-webpack-plugin, but that repository seems to no longer exist. I think it was migrated to slackhq
.
I don't know what caused dependabot to show the old URL, but maybe adding some URLs to package.json helps? I noticed in https://www.npmjs.com/package/csp-html-webpack-plugin that there are no links in the sidebar.
x
in one of the [ ]
)x
in each of the [ ]
)Hi, can you please upgrade this to the latest version to fix vulnerabilities?
Describe your issue here.
x
in one of the [ ]
)x
in each of the [ ]
)Being able to enable/disable nonces for each directive is really nice, but in my specific case I want to disable all usage of nonces and the list of directives is steadily growing. If csp-html-webpack-plugin
updates and adds support for a new directive, I have to remember to disable that one too, and truth be told: I'll likely forget to do that.
If the option could take a value of true
to enable all (supported) directives and false
to disable all, that'd be pretty nice :-)
As an example:
before:
nonceEnabled: {
'base-uri': false,
'child-src': false,
'connect-src': false,
'default-src': false,
'font-src': false,
'form-action': false,
'frame-ancestors': false,
'frame-src': false,
'img-src': false,
'manifest-src': false,
'media-src': false,
'object-src': false,
'script-src': false,
'style-src': false,
'trusted-types': false,
'worker-src': false
}
after:
nonceEnabled: false
Currently the plugin does not honor "XHTML mode": for example, if we have a configuration like this:
new HtmlWebpackPlugin({
filename: 'index.html',
template: './src/index.html',
xhtml: true,
})
the plugin will still output html-style tags (e.g., <meta charset="utf-8">
instead of <meta charset="utf-8"/>
).
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 4.0.0
node version: 12.17.0
OS version(s): any
See above - create a Webpack config with xhtml: true
set for html-webpack-plugin
The generated HTML should have self-closing tags where appropriate, like
<meta charset="utf-8"/>
The generated markup does not honor xhtml: true
:
<meta charset="utf-8">
The HTML output has an invalid doctype line like this:
<!DOCTYPE >
This happens even with an extremely minimal configuration file, see below.
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 5.1.0
node version: v22.5.1
OS version(s): Arch Linux
$ git clone https://github.com/ttencate/csp-html-webpack-plugin_doctype_repro.git
$ cd csp-html-webpack-plugin_doctype_repro
$ yarn install
$ ./node_modules/.bin/webpack
$ head -n1 dist/index.html
<!DOCTYPE html>
<!DOCTYPE >
package.json
{
"name": "repro",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"csp-html-webpack-plugin": "^5.1.0",
"html-webpack-plugin": "^5.6.0",
"webpack": "^5.94.0",
"webpack-cli": "^5.1.4"
}
}
webpack.config.js
const CspHtmlWebpackPlugin = require('csp-html-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
plugins: [
new HtmlWebpackPlugin(),
new CspHtmlWebpackPlugin(),
],
}
src/index.js
// Empty.
If your source HTML has a <noscript>
element with e.g. an inline <style>
child element, that style is not getting hashed and no hash corresponding to it can be found in the meta CSP tag in the output.
I imagine that styles within a <noscript>
can and should be included when hashes are being generated.
I have looked into this and it is related to cheerio's load()
function, which by default uses parse5
, which acts as a javascript-enabled user agent, and so when parse5 parses the input HTML, it properly (from its perspective) does not parse the contents of a <noscript>
(or more accurately it does parse it but returns the contents as plain text rather than DOM nodes).
Cheerio can be configured to use htmlparser2
, and when we do that, it handles the <noscript>
as desired and we get the children DOM elements (e.g. the <style>
). However it seems that explicitly configuring cheerio to use htmlparser2 is done via an internal undocumented option: _useHtmlParser2: true
which may not be safe for consumers such as this package to use.
You can also use cheerio's xmlMode: true
option which also parses <noscript>
as desired, but that changes the output HTML into an XML document and has all sorts of unwanted (most likely) side effects for the generated HTML.
References:
cheeriojs/cheerio#1105
inikulin/parse5#105
https://github.com/fb55/htmlparser2
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 4.0.0
node version: 10.19.0
OS version(s): macOS Catalina version 10.15.5
<noscript>
element with a simple inline <style>
child element e.g. this index.ejs
template<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<noscript>
<style>
.disabled-javascript {
color: red;
}
</style>
</noscript>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
template
csp-html-webpack-plugin
as follows:new CspHtmlWebpackPlugin({
'base-uri': "'self'",
'object-src': "'none'",
'script-src': ["'self'"],
'style-src': ["'self'"]
}, {
enabled: true,
hashingMethod: 'sha256',
hashEnabled: {
'script-src': true,
'style-src': true
},
nonceEnabled: {
'script-src': false,
'style-src': false
}
})
In the generated CSP meta tag, I should see a corresponding hash entry in the style-src
directive
In the generated CSP meta tag, I only see 'self'
in the style-src
directive.
Logs, screenshots, screencast, sample project, funny gif, etc.
The last commit was in September 2021, and there are 15 pending pull requests.
If this plugin is no longer maintained, please consider updating the README to say so.
nonce values are being added to the script and style tags in my HTML, but the nonces aren't in the CSP string itself. This appears similar to #93 but I'm on Mac OS and I'm using the latest node v14.
I am using an HTML template. A minimal webpack config with this exact template does not exhibit the issue, which makes me think something about my more complex webpack config is preventing the nonces from being added to the CSP.
Curiously, hashes for inline scripts do show up in the CSP string, so it is definitely being generated.
x
in one of the [ ]
)x
in each of the [ ]
)I am using this config to generate a CSP.
plugins: [
new HtmlWebpackPlugin({
template: 'src/www/index.tpl.html',
inject: 'body',
filename: 'index.html'
}),
new CspHtmlWebpackPlugin({
'script-src': '',
'style-src': ''
}),
// I am using other plugins after these: mini-css-extract-plugin, webpack.IgnorePlugin, copy-webpack-plugin, dotenv-webpack, webpack.ProvidePlugin
]
It results in a CSP like the following:
<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; object-src 'none'; script-src 'sha256-ABCXYZ=' … 'sha256-123999'; style-src ">
That is: it creates a CSP using hashes for inline scripts, but there are no nonces for script-src
or style-src
. The nonce
attribute is present in a number of <script>
and <style>
tags in the final HTML document.
slackhq/csp-html-webpack-plugin version: 5.1.0
node version: 14.19.3
OS version(s): Mac OS 12.4
The CSP content to have the nonce values in it.
The nonce values are attached to the script and style tags but are not present in the CSP string itself.
Logs, screenshots, screencast, sample project, funny gif, etc.
I'm not sure if this is a bug or if my config is off but although I see the Content-Security-Policy meta tag generated in /build/index.html, I still don't see the header presenting in the response headers in the browser. I am using a Lambda for the other required headers but as is the purpose of this library, I can't whitelist my constantly changing chunk so I've decided to configure just CSP in a meta tag with this plug-in. I followed this article to implement it: https://medium.com/@nrshahri/csp-cra-324dd83fe5ff
Does anyone have any insight here as to why the header isn't visible? Can I not mix with Lambda?
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 3.0.4
node version: 8.10.0
OS version(s): Ubuntu 18.04
What you expected to happen
What actually happened
Logs, screenshots, screencast, sample project, funny gif, etc.
Hi,
Can you please upgrade to Cheerio 1.0.0-rc.4?
Cheerio 1.0.0-rc.4 uses Lodash 4.17.20 which fixes vulnerabilities.
Was wondering if anyone was using this with a Helm nginx + configmap deployment where some environments have different values. I'd like to be able to set a domain for test (.test.com) and a domain for production (.prod.com) with the helm chart but also have it work with values files.
Currently our values files have directives set and are overridden as needed with a values.prod.yaml file, etc.
Off the top of my head, I suppose it could be solved by creating multiple output files for each environment and the values file would inject into the config map the proper csp file output, but maybe there is a better solution?
If anyone is doing something similar and has any suggestions or comments please share as I'd like to learn the best process.
x
in one of the [ ]
)x
in each of the [ ]
)I used the latest create-react-app CLI to bootstrap my project and then I ejected it. The latest create-react-app uses "html-webpack-plugin" version 4.0.0-alpha.2. When I use "csp-html-webpack-plugin" with it I am getting the following error
Cannot read property 'tapAsync' of undefined
I have already tried placing "csp-html-webpack-plugin" at the end of the plugins list after "html-webpack-plugin" and still I am getting the same issue.
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 2.3.0
node version: 8.12.0
OS version(s): OSX Mojave
Expected the build to complete
Got the error "Cannot read property 'tapAsync' of undefined"
remove package @types/anymatch
x
in one of the [ ]
)x
in each of the [ ]
)npm WARN deprecated @types/[email protected]: This is a stub types definition. anymatch provides its own type definitions, so you do not need this installed.
slackhq/csp-html-webpack-plugin version:3.0.1
node version: v14.16.1
OS version(s): MacOS 11.3.1
Straight from the docs, we can see this:
new HtmlWebpackPlugin({
cspPlugin: {
enabled: true,
policy: {
'base-uri': "'self'",
'object-src': "'none'",
'script-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"],
'style-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"]
},
hashEnabled: {
'script-src': true,
'style-src': true
},
nonceEnabled: {
'script-src': true,
'style-src': true
}
}
});
new CspHtmlWebpackPlugin({
'base-uri': "'self'",
'object-src': "'none'",
'script-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"],
'style-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"]
}, {
enabled: true,
hashingMethod: 'sha256',
hashEnabled: {
'script-src': true,
'style-src': true
},
nonceEnabled: {
'script-src': true,
'style-src': true
}
})
It tells us about the default options, but it fails to tell us that it can be used one way or another.
If that's not the case, well, it works that way for me. I was looking at the docs for the first time and immediately thought that configuration must be placed within both places, which is weird. But that doesn't seem to be the case. We don't have to define cspPolicy
property within HTMLWebpackPlugin
if we are using CspHtmlWebpackPlugin
.
Anyways, aside from this, I came across a real issue.
The option hashEnabled
does not seem to be working. If I set both properties to true
or to false
, it does nothing... No hash calculations of internal scripts and styles, so they are nowhere to be found within CSP tag.
However, if I only enable nonceEnabled
it seems to be working, not quite sure YET, but I can see nonce
hashes in the CSP tag. Howevever, nonce
should be different for each page load, so that's not really what I'm looking for in my SPA.
x
in one of the [ ]
)x
in each of the [ ]
)I assume it's a bug, but it might be a misunderstanding of usage.
hashEnabled
– not working.
slackhq/csp-html-webpack-plugin version: ^3.0.4
node version: v13.11.0
OS version(s): macOS Catalina 10.15.3 (19D76)
vue-json-pretty
npm package, as it will inject style
on each load. Any plugin will do, but this is an example. You might also make a small script that will inject some CSS.To have SHA-256 hashes within my CSP policy for internal scripts and styles.
Nothing. It literally does nothing.
Describe your issue here.
x
in one of the [ ]
)x
in each of the [ ]
)If i use this CSP configuration on Mac
new CspHtmlWebpackPlugin(
{
'script-src': ['\'strict-dynamic\''],
'style-src': ['\'self\''],
'frame-src': ['\'none\''],
'worker-src': ['\'none\'']
},
{
enabled: true,
hashingMethod: 'sha512',
hashEnabled: {
'script-src': true,
'style-src': true
},
nonceEnabled: {
'script-src': true,
'style-src': true,
},
}
But if i run the same on windows pc nonces doesn't will be added to content property of CSP's meta tag
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; object-src 'none'; script-src 'nonce-gn67IhFu2jJyrwY+PMSeUA==' 'strict-dynamic'; style-src 'self' 'nonce-y3gcK9oDtWf74QiBnf2rSA=='; frame-src 'none'; worker-src 'none'">
<meta charset="UTF-8">
<title>Title</title>
<script defer="defer" src="static/js/main.ba2c44d7bc58ccf6207d.bundle.js" nonce="gn67IhFu2jJyrwY+PMSeUA=="> </script>
<link href="static/css/main.6ec92936e5acaa7eae9f.bundle.css" rel="stylesheet" nonce="y3gcK9oDtWf74QiBnf2rSA==">
</head>
<body>
<div id="root"></div>
</body>
</html>
slackhq/csp-html-webpack-plugin version: ^5.1.0
node version:I'm using electron with node v12, but i've installed the latest LTS version
OS version(s):10.0.19041
1.Use my configuration on both OS
2.
3.
What you expected to happen: the same that happen on Mac
I am having an issue with this plugin and MaterialUI's withStyles functionality which allows me to write styles within JSX and generate a stylesheet dynamically. Generally I will receive the following error:
addStyles.js:397 Refused to load the stylesheet 'blob:https://host' because it violates the following Content Security Policy directive: "style-src 'unsafe-inline' 'self' 'unsafe-eval' 'sha256-8Ttgnzta3WC0XhMHqjlso6w8jFtMRzqTSufL6OFT/HQ=' 'nonce-hr9a9a5KipK/nNqlYwCf9w==' 'nonce-raSGmUULzSOykrZn2AzKOQ==' 'nonce-gm6b/nNJzNSSPll0/D8N4A==' 'nonce-0Ij+YWTEfMPWwdJ4aEg5Pw==' 'nonce-lylYG0q6NSXffVaHd+ydrg==' 'nonce-5ZbhjP2mnLu3e+iAvMFDlw==' 'nonce-2eJx+0YItmKXInI0rfaqNw==' 'nonce-1OyIfAm7sHSq2rZRWPWFCw==' 'nonce-4AdZFYimCELi/0L9XhjJ7A==' 'nonce-UCQAVe9izKqG5vo16urKXg==' 'nonce-ykGZtSKbUJYJaHJOeYNIeA==' 'nonce-tVmIhhp0G3aSy6E3dby1hg==' 'nonce-8VOErQfHOdp+kr9Sgv/+xg==' 'nonce-nhC9
I use CRA's ejected webpack. I have tried to implement various fixes to get your plugin to play nicely with Material UI withStyles but have been unsuccessful.
x
in one of the [ ]
)x
in each of the [ ]
)Is anyone familiar with how to get this plugin to work nicely with Material UI and webpack?
Describe your issue here.
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 2.5.0
node version: 10
OS version(s): Windows 10 & Mac OXS
disableCspPlugin: true
for files that are not index.htmlconst path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = new HtmlWebpackPlugin({
template: './manifest.ejs',
chunks: [],
filename: 'manifest.json',
inject: false,
hash: false,
minify: false,
// csp plugin
disableCspPlugin: true
});
// template ./manifest.ejs
<% const package = require('../../../package.json')%>
{
"name": "<%=package.name%>",
}
csp-html-webpack-plugin does NOT modify my template since it is disabled
What you expected to happen:
{
"name": "repo-name",
}
<html><head></head><body>{
"name": "repo-name",
}
</body></html>
What actually happened
even though the user specify disableCspPlugin: true
, the plugin still mutates the template:
Slack has recently updated it's contributor agreement to cover all Slack projects you might contribute to instead of just this one
As contributors to the csp-html-webpack-plugin
, I'd appreciate if you wouldn't mind signing this new agreement to transfer your signature over! You rights don't change in doing so
https://cla-assistant.io/slackhq/hack-json-schema
(the url has hack-json-schema
in it, but it covers all slack projects you might contribute to)
Please do let me know if you have any questions -- I'd be happy to get back to you with answers!
cc @sibiraj-s @wanecek @swac @pierroberto @ScottRocha @Daniel-Khodabakhsh
babel-jest
appears in the regular dependencies, so it's getting installed along with the rest of the code.
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 3.0.0
node version: 8, 10
OS version(s): macOS 10.14 (Mojave)
npm i csp-html-webpack-plugin
Only the deps which are actually consumed are installed along with csp-html-webpack-plugin
babel-jest is present. Also you get a warning if you don't satisfy babel-jest's peerDependency for babel-core.
Describe your issue here.
Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 5.0.1
node version: 14
OS version(s): windows 10
git checkout http://github.com/david-fong/snakey3.git
cd snakey3
git checkout 396fe45
./scripts/pack -t
file:///.../snakey3/dist/client/index.html
and observe error for incorrect script sha in the browser devtools.git checkout @~ && ./scripts/pack
, then open again and observe that there is no such error.I'm not sure why this happens.
I expect that bumping from version 5.0.0 to 5.0.1 shouldn't break anything.
Something broke.
I use an ejected CRA webpack.config.js. When adding your plugin and trying to generate a CSP meta tag, nothing is appended to HTML. Any idea how I can get this to work?
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
cra 2.0.0
node version: 8.6
OS version(s):
Here is my webpack.config.js snippet:
new HtmlWebpackPlugin(
{
cspPlugin: {
enabled: true,
policy: {
'base-uri': "'self'",
'object-src': "'none'",
'script-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"],
'style-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"]
},
hashEnabled: {
'script-src': true,
'style-src': true
},
nonceEnabled: {
'script-src': true,
'style-src': true
}
}
},
{
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined
),
new CspHtmlWebpackPlugin({
'base-uri': "'self'",
'object-src': "'none'",
'script-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"],
'style-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"]
}, {
enabled: true,
hashingMethod: 'sha256',
hashEnabled: {
'script-src': true,
'style-src': true
},
nonceEnabled: {
'script-src': true,
'style-src': true
}
}),
tag appended to html
Nothing is appended
Trying to use this plugin within a static website is opening security holes by default.
For example if we follow #53, it will add static nonces on a static website.
I would recommend to disable nonces by default, and let the user enable them on when they know that they wont pack a static website
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 5.1.0
npx create-react-app my-app --template typescript
npm install react-app-rewired csp-html-webpack-plugin --save-dev
config-overrides.js
const CspHtmlWebpackPlugin = require("csp-html-webpack-plugin");
module.exports = function override(config, env) {
config.plugins.push(
new CspHtmlWebpackPlugin({
"script-src": "",
"style-src": "",
})
);
return config;
};
react-app-rewired build
build/index.html
fileNonces are not static. At the very least, they should be generated by an inline script and injected
Static nonces are generated.
Uploading this to a CDN will allow anyone to grab the nunce and re-use it, bypassing the CSP
<meta http-equiv="Content-Security-Policy"
content="base-uri 'self'; object-src 'none'; script-src 'nonce-csu9vwLV51tCaN6biAAJFg=='; style-src 'nonce-vAVCeRTmI/cROWHcZcycQA=='">
Plugin generates wrong hashes since 5.0.1
Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin versions: 5.0.1 - 5.1.0
node versions: 14.16.0 and 14.17.0
OS version(s): Windows 10
Removed
Hello,
I am using HtmlWebpackPlugin to define an index.ejs file as template. I am also passing some templateParameters through the HtmlWebpackPlugin (below given random names for security but you get the picture). If I leave the csp meta tag in the index.ejs, it doesn't get overwritten by your csp plugin, and if I remove it completely then it's not even created. I must add that I am using webpack-dev-server with hot reloading to develop and test it locally. I am giving you an excerpt of both plugin configurations up till now, could you maybe shed some light as to how to use them properly?
// ... rest of code
const cspOptions = {
'script-src': ['"self"', '"unsafe-eval"', '"resource:"'],
'style-src': ['"self"', '"unsafe-inline"'],
'connect-src': ['"blob:"', '"http://localthost:*"', '"ws://localhost:*"'],
'font-src': '"self"',
'object-src': '"blob:"',
'img-src': ['"data:"', '"self"'],
'media-src': '"self"',
'form-action': '"self"',
'child-src': ['"blob:"'],
'worker-src': ['"blob:"', '"resource:"'],
'frame-src': ['"blob:"', '"self"'],
'base-uri': '"resource"',
'block-all-mixed-content': true // Is this even working like that?
};
new HtmlWebpackPlugin({
cspPlugin: {
enabled: true,
policy: cspOptions,
}
inject: false,
template: './public/index.ejs',
templateParameters: {
platform: 'browser',
mode: 'development',
pathPrefix: './',
backend: 'http://localhost:3001',
metaDescription: 'Testing CSP',
title: 'Test App',
},
minify: false
}),
new CspHtmlWebpackPlugin(cspOptions)
// ... rest of code
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: v3.0.4
node version: v8.11.1
OS version(s): Windows 10
Have an overwritten csp meta tag within the built index.html or if it wasn't existing have a new csp meta tag created with this plugin's configuration
No meta tag is overwritten or created based on this plugin's configuration
Hi, thank you for this great plugin!!
When tweaking my CSP in webpack.config.js
, I found myself stopping and restarting my webpack server for my CSP changes to be taken into account. I ended up using nodemon to do this automatically and save time. I think this may be a common workflow, since setting up CSP involves tweaking and back-and-forth.
Do you think it would make sense for the README to include a note on how to set this up?
This is what I did:
nodemon.json
in my project root:{
"watch": ["webpack.config.js"],
"exec": "node scripts/start.js" // = what was in my package.json's start script
}
"start:watch:webpack": "nodemon",
npm run start:watch:webpack
when setting up my CSP.x
in one of the [ ]
)x
in each of the [ ]
)The <meta http-equiv="content-security-policy" content="">
tag should be created automatically if it's not present in the template.
Not everyone uses an explicit template, and instead uses the template automatically generated by HtmlWebpackPlugin.
I am not seeing hashes in the meta tag when I expected I would. I do seem to get nonces, but they don't appear to work.
x
in one of the [ ]
)x
in each of the [ ]
)If I use this as my webpack configuration:
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_index.html",
template: "app/html/index_template.html",
chunks: [ "app" ],
cspPlugin: {
enabled: true,
policy: {
"base-uri": "'self'",
"object-src": "'none'",
"script-src": [ "https://127.0.0.1:8080", "'self'" ],
"style-src": [ "https://127.0.0.1:8080", "'self'"],
"font-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'" ],
},
hashEnabled: {
"script-src": true,
"style-src": true,
},
nonceEnabled: {
"script-src": true,
"style-src": true,
},
},
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_popup.html",
template: "app/html/popup_template.html",
chunks: [ "form" ],
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_codemirror.html",
template: "app/html/codemirror_template.html",
chunks: [ "editor" ],
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_error_wrapper.html",
template: "app/html/error_wrapper_template.html",
chunks: [ "error" ],
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_documentation.html",
template: "app/html/documentation_template.html",
chunks: [ "docs_entry" ],
} ),
new CspHtmlWebpackPlugin( {
"base-uri": "'self'",
"object-src": "'none'",
"script-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'" ],
"style-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'"],
"font-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'" ],
}, {
enabled: true,
hashingMethod: "sha256",
hashEnabled: {
"script-src": true,
"style-src": true,
},
nonceEnabled: {
"script-src": false,
"style-src": false,
},
} ),
then it produces this output (for the app chunk):
<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; object-src 'none'; script-src https://127.0.0.1:8080 'self' 'nonce-iy87WccFQS7zHW0XbzFJCw=='; style-src https://127.0.0.1:8080 'self' 'nonce-eqk3Sox+amk9wfdSl3g5GQ=='; font-src 'unsafe-inline' 'unsafe-eval' https://127.0.0.1:8080 'self'>
and I see this error:
<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; object-src 'none'; script-src https://127.0.0.1:8080 'self' 'nonce-iy87WccFQS7zHW0XbzFJCw=='; style-src https://127.0.0.1:8080 'self' 'nonce-eqk3Sox+amk9wfdSl3g5GQ=='; font-src 'unsafe-inline' 'unsafe-eval' https://127.0.0.1:8080 'self'; connect-src 'unsafe-inline' 'unsafe-eval' https://127.0.0.1:8080 'self' https://ipv4.icanhazip.com wss://127.0.0.1:8080 https://api.keygen.sh">
which is coming from addStyles.js, part of the style-loader package.
If I now set the nonce enabled to be false, as below:
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_index.html",
template: "app/html/index_template.html",
chunks: [ "app" ],
cspPlugin: {
enabled: true,
policy: {
"base-uri": "'self'",
"object-src": "'none'",
"script-src": [ "https://127.0.0.1:8080", "'self'" ],
"style-src": [ "https://127.0.0.1:8080", "'self'"],
"font-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'" ],
},
hashEnabled: {
"script-src": true,
"style-src": true,
},
nonceEnabled: {
"script-src": false,
"style-src": false,
},
},
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_popup.html",
template: "app/html/popup_template.html",
chunks: [ "form" ],
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_codemirror.html",
template: "app/html/codemirror_template.html",
chunks: [ "editor" ],
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_error_wrapper.html",
template: "app/html/error_wrapper_template.html",
chunks: [ "error" ],
} ),
new HtmlWebpackPlugin( {
filename: "../app/html/webpack_documentation.html",
template: "app/html/documentation_template.html",
chunks: [ "docs_entry" ],
} ),
new CspHtmlWebpackPlugin( {
"base-uri": "'self'",
"object-src": "'none'",
"script-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'" ],
"style-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'"],
"font-src": [ "'unsafe-inline'", "'unsafe-eval'", "https://127.0.0.1:8080", "'self'" ],
}, {
enabled: true,
hashingMethod: "sha256",
hashEnabled: {
"script-src": true,
"style-src": true,
},
nonceEnabled: {
"script-src": false,
"style-src": false,
},
} ),
then it produces this output (for the app chunk):
<meta http-equiv="Content-Security-Policy" content="base-uri 'self'; object-src 'none'; script-src https://127.0.0.1:8080 'self'; style-src https://127.0.0.1:8080 'self'; font-src 'unsafe-inline' 'unsafe-eval' https://127.0.0.1:8080 'self'>
and I see this error:
Refused to apply inline style because it violates the following Content Security Policy directive: "style-src https://127.0.0.1:8080 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU='), or a nonce ('nonce-...') is required to enable inline execution.
If I delete the nonceEnabled section in the app chunk settings then I get the same result as setting them to false.
So my questions are why am I not getting hashed generated and what do I need to do so that thye are generated and secondly, why is the nonce that is generated not working - how can I tell what the nonce relates to ?
Thanks for your help.
slackhq/csp-html-webpack-plugin version: 3.0.1
node version: 10.13
OS version(s): Windows 10
As its a question I have not tried to reproduce the issue in a cut down setup.
Expected to see hashes inserted into the meta tag
Nonces were inserted, but seemed to have no effect.
None
I have a question in regard to nonceEnabled
:
I assume that the csp-html-webpack-plugin
is only invoked at build time and not for every http request. If this assumption is correct, how can one prevent attackers from just copying CSP nonces and by that bypassing the entire CSP?
Relevant section in the CSP spec is here: https://w3c.github.io/webappsec-csp/#security-nonces
x
in one of the [ ]
)x
in each of the [ ]
)Hi again :) As a newcomer to this (great!) plugin, a few things in the README.md
caused minor friction for me.
I've listed a few suggestions for tweaks in README.md
below. Not all of these may make sense, so feel free to point out to the ones you think don't or do!
const CspHtmlWebpackPlugin = require('csp-html-webpack-plugin');
for example in this section?unsafe-eval
with something else? To encourage the use of safe policies. And because if other developers are lazy like me, they first may copy the example policy into their code before editing it (and—pushing the idea a bit here—it's not impossible to forget to remove unsafe-eval
). unsafe-inline
feels more OK, since AFAIK it's needed in Safari.processFn: defaultProcessFn
or adding an // optional
comment above it? Why: as mentioned, my first reflex was to paste the full config example CSP to save myself some typing time. And so I ran into defaultProcessFn is not defined
—which was a super quick one to fix, but it did require me to go back and edit my config. Maybe the question here is if you expect this feature to be used by most / a large part of this plugin's users? On the plus side though: this error was actually a good way for me to discover the feature / this ability to change the default method of what happens to the CSP after it has been created...x
in one of the [ ]
)x
in each of the [ ]
)In order to properly test the introduction of new CSPs, it would be amazing if the plugin was able to also output a meta tag with http-equiv="Content-Security-Policy-Report-Only"
. Ideally, these tags could co-exist, so you can leave the already active CSPs in place, while testing new policies at the same time, i.e. it would allow two separate configurations.
I'm happy to contribute if the feature fits the scope of this plugin and nothing is in the pipeline yet...
x
in one of the [ ]
)x
in each of the [ ]
)At @productboard we plan to use this plugin (thanks for that!). We use script preloads to optimize loading experience. I propose that nonces should be also added on those.
<link rel="preload" href="..." as="script" crossorigin="anonymous">
x
in one of the [ ]
)x
in each of the [ ]
)I'm using the plugin with .cshtml file.
My template is like this:
@using System.Threading;
@using SOME.Controllers;
@{
var app = ViewBag.NgModule != null ? ViewBag.NgModule : "SOME";
var ie8 = IsIE() && GetIEVersion() <= 8;
}
<!DOCTYPE html>
<html lang="en" ng-app="@app" id="ng-app" class="height100">
<head>
<meta charset="utf-8" />
@if (string.IsNullOrWhiteSpace(ViewBag.Title))
{
<title>SOMEShare & Collect</title>
}
else
{
<title>@ViewBag.Title</title>
}
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta http-equiv="content-security-policy" content="" />
...
The output I'm getting is like this:
<html lang="en" ng-app="@app" id="ng-app" class="height100"><head><meta http-equiv="Content-Security-Policy" content="base-uri 'self'; object-src 'none'; script-src 'self' 'unsafe-eval' 'nonce-n1st7Y/9LxdP2jtjoIB/RA=='; style-src 'self' 'unsafe-inline'; default-src 'self' https://some.rocket.chat; worker-src 'slef' blob: data: 'unsafe-eval' 'unsafe-inline'; frame-src 'self' https://some.rocket.chat; font-src 'self' https://kendo.cdn.telerik.com data:; img-src 'self' data:; connect-src 'self' https://some.rocket.chat"></head><body class="height100">@using System.Threading;
@using SOME.Controllers;
@{
var app = ViewBag.NgModule != null ? ViewBag.NgModule : "SOME";
var ie8 = IsIE() && GetIEVersion() <= 8;
}
<meta charset="utf-8">
@if (string.IsNullOrWhiteSpace(ViewBag.Title))
{
<title>SOME Share & Collect</title>
}
else
{
<title>@ViewBag.Title</title>
}
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon">
<meta http-equiv="content-security-policy" content>
x
in one of the [ ]
)x
in each of the [ ]
)In order for webpack-html-plugin to work with these files I'm using this in my .cshtml template
<%= Object.keys(htmlWebpackPlugin.files.chunks).map(k => {
return `<script src="~/Scripts${htmlWebpackPlugin.files.chunks[k].entry}"></script>`;
}).join('\n') %>
It seems I need something similar for the csp-html-webpack-plugin.
Is there a better way to do it, that is not documented?
If this plugin is enabled, escaped html (ex. '<' or '>' ) becomes unescaped.
So, this behavior makes unexpected output, and maybe causes potential bug.
For example:
Before
<html>
<body>
<h1>This is not h1.<h1>
</body>
</html>
After
<html>
<body>
<h1>This is not h1.</h1>
</body>
</html>
Also I found below issue (cheerio's one). This plugin uses cheerio, so it seems below issue is root cause.
cheeriojs/cheerio#1219
Do you have any solutions?
x
in one of the [ ]
)x
in each of the [ ]
)Filling out the following details about bugs will help us solve your issue sooner.
slackhq/csp-html-webpack-plugin version: 3.0.2
node version: v12.4.0
OS version(s): ArchLinux (latest)
new CspHtmlWebpackPlugin()
to webpack config to enable this pluginEscaped html should be escaped.
Escaped html becomes unescaped.
My webpack config (plugins section):
plugins: [
new MiniCssExtractPlugin({
filename: 'style/style-[hash].css'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.join(__dirname, 'src', 'index.html')
}),
new CspHtmlWebpackPlugin(),
new CopyWebpackPlugin([
{from: path.join(__dirname, 'src', 'favicon.ico'), to: './'},
{from: path.join(__dirname, 'src', 'images'), to: 'images'},
]),
]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.