webpack-subresource-integrity
Webpack plugin for enabling Subresource Integrity.
Subresource Integrity (SRI) is a security
feature that enables browsers to verify that files they fetch (for
example, from a CDN) are delivered without unexpected
manipulation.
Features
- Optional integration with html-webpack-plugin
- Support for code-splitting (integrity for lazy-loaded chunks)
- Compatible with Webpack 1.x and 2.x
Installation
npm install webpack-subresource-integrity --save-dev
Webpack Configuration Example
import SriPlugin from 'webpack-subresource-integrity';
const compiler = webpack({
output: {
crossOriginLoading: 'anonymous',
},
plugins: [
new SriPlugin({
hashFuncNames: ['sha256', 'sha384'],
enabled: process.env.NODE_ENV === 'production',
}),
],
});
Setting the integrity
attribute for top-level assets
For the plugin to take effect it is essential that you set the
integrity
attribute for top-level assets (i.e. assets loaded by your
HTML pages.)
With HtmlWebpackPlugin
When html-webpack-plugin is injecting assets into the template (the
default), the integrity
attribute will be set automatically. The
crossorigin
attribute will be set as well, to the value of
output.crossOriginLoading
webpack option. There is nothing else to
be done.
With HtmlWebpackPlugin({ inject: false })
When you use html-webpack-plugin with inject: false
, you are
required to set the integrity
and crossorigin
attributes in your
template as follows:
<% for (var index in htmlWebpackPlugin.files.js) { %>
<script
src="<%= htmlWebpackPlugin.files.js[index] %>"
integrity="<%= htmlWebpackPlugin.files.jsIntegrity[index] %>"
crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
></script>
<% } %>
<% for (var index in htmlWebpackPlugin.files.css) { %>
<link
href="<%= htmlWebpackPlugin.files.css[index] %>"
integrity="<%= htmlWebpackPlugin.files.cssIntegrity[index] %>"
crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
rel="stylesheet"
/>
<% } %>
Without HtmlWebpackPlugin
The correct value for the integrity
attribute can be retrieved from
the integrity
property of Webpack assets. However, that property is
not copied over by Webpack's stats
module so you'll have to access
the "original" asset on the compilation
object. For example:
compiler.plugin("done", stats => {
const mainAssetName = stats.toJson().assetsByChunkName.main;
const integrity = stats.compilation.assets[mainAssetName].integrity;
});
Note that you're also required to set the crossorigin
attribute. It
is recommended to set this attribute to the same value as the webpack
output.crossOriginLoading
configuration option.
Options
hashFuncNames
Required option, no default value.
An array of strings, each specifying the name of a hash function to be
used for calculating integrity hash values. For example, ['sha256', 'sha512']
.
See SRI: Cryptographic hash functions
enabled
Default value: true
When this value is falsy, the plugin doesn't run and no integrity
values are calculated. It is recommended to disable the plugin in
development mode.
crossorigin
DEPRECATED. Use webpack option output.crossOriginLoading
instead.
Default value: "anonymous"
When using HtmlWebpackPlugin({ inject: true })
, this option
specifies the value to be used for the crossorigin
attribute for
injected assets.
The value will also be available as
htmlWebpackPlugin.options.sriCrossOrigin
in html-webpack-plugin
templates.
See
SRI: Cross-origin data leakage and
MDN: CORS settings attributes
Caveats
Browser support
Browser support for SRI is currently patchy. Your page will still
work on browsers without support for SRI, but subresources won't be
protected from tampering.
See Can I use Subresource Integrity?
Broken browser versions
There is a
known bug relating to SRI in Chrome 45 and 46
which will break loading of scripts containing certain UTF-8
characters. You might want to hold off using SRI if you need to
support these Chrome versions. (Unfortunately, Chrome 45 still
holds a relatively high market share
of around 5% at the time of this writing.)
Hot Module Replacement
Chunks loaded via Hot Module Replacement (HMR) are not currently
protected. This shouldn't be a problem because HMR is usually used
only in development mode where SRI is not normally needed.
Further Reading
License
Copyright (c) 2015, 2016 Waysact Pty Ltd
MIT (see LICENSE)