csp-html-webpack-plugin
v5.1.0
Published
A plugin which, when combined with HTMLWebpackPlugin, adds CSP tags to the HTML output
Downloads
176,280
Readme
CSP HTML Webpack Plugin
About
This plugin will generate meta content for your Content Security Policy tag and input the correct data into your HTML template, generated by html-webpack-plugin.
All inline JS and CSS will be hashed and inserted into the policy.
Installation
Install the plugin with npm:
npm i --save-dev csp-html-webpack-plugin
Basic Usage
Include the following in your webpack config:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CspHtmlWebpackPlugin = require('csp-html-webpack-plugin');
module.exports = {
// rest of webpack config
plugins: [
new HtmlWebpackPlugin()
new CspHtmlWebpackPlugin({
// config here, see below
})
]
}
Recommended Configuration
By default, the csp-html-webpack-plugin
has a very lax policy. You should configure it for your needs.
A good starting policy would be the following:
new CspHtmlWebpackPlugin({
'script-src': '',
'style-src': ''
});
Although we're configuring script-src
and style-src
to be blank, the CSP plugin will scan your HTML
generated in html-webpack-plugin
for external/inline script and style tags, and will add the appropriate
hashes and nonces to your CSP policy. This configuration will also add a base-uri
and object-src
entry
that exist in the default policy:
<meta http-equiv="Content-Security-Policy" content="
base-uri 'self';
object-src 'none';
script-src 'sha256-0Tumwf1AbPDHZO4kdvXUd4c5PiHwt55hre+RDxj9O3Q='
'nonce-hOlyTAhW5QI5p+rv9VUPZg==';
style-src 'sha256-zfLUTOi9wwJktpDIoBZQecK4DNIVxW8Tl0cadROvQgo='
">
This configuration should work for most use cases, and will provide a strong layer of extra security.
All Configuration Options
CspHtmlWebpackPlugin
This CspHtmlWebpackPlugin
accepts 2 params with the following structure:
{object}
Policy (optional) - a flat object which defines your CSP policy. Valid keys and values can be found on the MDN CSP page. Values can either be a string, or an array of strings.{object}
Additional Options (optional) - a flat object with the optional configuration options:{boolean|Function}
enabled - if false, or the function returns false, the empty CSP tag will be stripped from the html output.- The
htmlPluginData
is passed into the function as it's first param. - If
enabled
is set the false, it will disable generating a CSP for all instances ofHtmlWebpackPlugin
in your webpack config.
- The
{string}
hashingMethod - accepts 'sha256', 'sha384', 'sha512' - your node version must also accept this hashing method.{object}
hashEnabled - a<string, boolean>
entry for which policy rules are allowed to include hashes{object}
nonceEnabled - a<string, boolean>
entry for which policy rules are allowed to include nonces{Function}
processFn - allows the developer to overwrite the default method of what happens to the CSP after it has been created- Parameters are:
builtPolicy
: astring
containing the completed policy;htmlPluginData
: theHtmlWebpackPlugin
object
;$
: thecheerio
object of the html file currently being processedcompilation
: Internal webpack object to manipulate the build
- Parameters are:
HtmlWebpackPlugin
The plugin also adds a new config option onto each HtmlWebpackPlugin
instance:
{object}
cspPlugin - an object containing the following properties:{boolean}
enabled - if false, the CSP tag will be removed from the HTML which this HtmlWebpackPlugin instance is generating.{object}
policy - A custom policy which should be applied only to this instance of the HtmlWebpackPlugin{object}
hashEnabled - a<string, boolean>
entry for which policy rules are allowed to include hashes{object}
nonceEnabled - a<string, boolean>
entry for which policy rules are allowed to include nonces{Function}
processFn - allows the developer to overwrite the default method of what happens to the CSP after it has been created- Parameters are:
builtPolicy
: astring
containing the completed policy;htmlPluginData
: theHtmlWebpackPlugin
object
;$
: thecheerio
object of the html file currently being processedcompilation
: Internal webpack object to manipulate the build
- Parameters are:
Order of Precedence:
You don't have to include the same policy / hashEnabled
/ nonceEnabled
configuration object in both HtmlWebpackPlugin
and CspHtmlWebpackPlugin
.
- Config included in
CspHtmlWebpackPlugin
will be applied to all instances ofHtmlWebpackPlugin
. - Config included in a single
HtmlWebpackPlugin
instantiation will only be applied to that instance.
In the case where a config object is defined in multiple places, it will be merged in the order defined below, with former keys overriding latter. This means entries for a specific rule will not be merged; they will be replaced.
> HtmlWebpackPlugin cspPlugin.policy
> CspHtmlWebpackPlugin policy
> CspHtmlWebpackPlugin defaultPolicy
Appendix
Default Policy:
{
'base-uri': "'self'",
'object-src': "'none'",
'script-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"],
'style-src': ["'unsafe-inline'", "'self'", "'unsafe-eval'"]
};
Default Additional Options:
{
enabled: true
hashingMethod: 'sha256',
hashEnabled: {
'script-src': true,
'style-src': true
},
nonceEnabled: {
'script-src': true,
'style-src': true
},
processFn: defaultProcessFn
}
Full Default Configuration:
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
},
processFn: defaultProcessFn // defined in the plugin itself
}
});
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
},
processFn: defaultProcessFn // defined in the plugin itself
})
Advanced Usage
Generating a file containing the CSP directives
Some specific directives require the CSP to be sent to the client via a response header (e.g. report-uri
and report-to
)
You can set your own processFn
callback to make this happen.
nginx
In your webpack config:
const RawSource = require('webpack-sources').RawSource;
function generateNginxHeaderFile(
builtPolicy,
_htmlPluginData,
_obj,
compilation
) {
const header =
'add_header Content-Security-Policy "' +
builtPolicy +
'; report-uri /csp-report/ ";';
compilation.emitAsset('nginx-csp-header.conf', new RawSource(header));
}
module.exports = {
{...},
plugins: [
new CspHtmlWebpackPlugin(
{...}, {
processFn: generateNginxHeaderFile
})
]
};
In your nginx config:
location / {
...
include /path/to/webpack/output/nginx-csp-header.conf
}
Contribution
Contributions are most welcome! Please see the included contributing file for more information.
License
This project is licensed under MIT. Please see the included license file for more information.