SubresourceIntegrityPlugin

Added in v1.2.4Rspack only

The rspack.experiments.SubresourceIntegrityPlugin is a plugin for enabling Subresource Integrity in Rspack.

What is SRI

Subresource Integrity (SRI) is a security feature that enables browsers to verify that resources they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched resource must match.

For <script> tags, the result is to refuse to execute the code; for CSS links, the result is not to load the styles.

For more on subresource integrity, see Subresource Integrity - MDN.

Features

Support for HTML Plugin

The plugin supports integration with HtmlRspackPlugin and html-webpack-plugin. It will automatically set the integrity and crossorigin attributes for the injected tags.

Support for Code Splitting

The plugin supports code splitting. When you use dynamic imports, the plugin will automatically set the integrity and crossorigin attributes for the generated chunk loading tags.

Usage

You can use the plugin by importing it as an experimental plugin from @rspack/core:

rspack.config.mjs
import { experiments } from '@rspack/core';
const { SubresourceIntegrityPlugin } = experiments;

Or:

rspack.config.cjs
const {
  experiments: { SubresourceIntegrityPlugin },
} = require('@rspack/core');

The output.crossOriginLoading option is required for SRI to work:

rspack.config.mjs
import { experiments } from '@rspack/core';
const { SubresourceIntegrityPlugin } = experiments;

export default {
  output: {
    crossOriginLoading: 'anonymous',
  },
  plugins: [new SubresourceIntegrityPlugin()],
};

With HTML Plugin

When the HTML plugin(HtmlRspackPlugin or html-webpack-plugin) is used, the integrity and crossorigin attributes will be set automatically.

The SubresourceIntegrityPlugin will interact with HtmlRspackPlugin by default:

rspack.config.mjs
import { experiments, HtmlRspackPlugin } from '@rspack/core';
const { SubresourceIntegrityPlugin } = experiments;

export default {
  plugins: [new SubresourceIntegrityPlugin(), new HtmlRspackPlugin()],
};

If html-webpack-plugin is used, the htmlPlugin option should be specified to the path of it:

rspack.config.mjs
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { experiments } from '@rspack/core';
const { SubresourceIntegrityPlugin } = experiments;

export default {
  plugins: [
    new SubresourceIntegrityPlugin({
      // the path to the html-webpack-plugin
      htmlPlugin: import.meta.resolve('html-webpack-plugin'),
    }),
    new HtmlWebpackPlugin(),
  ],
};

With HTML Plugin and inject: false

If you use the HTML plugin with inject: false, you need to set the integrity and crossorigin attributes in your template manually.

With HtmlRspackPlugin, the grammar of the template is a bit different with .ejs(see here), you can inject them like this:

index.ejs
<% for src in htmlRspackPlugin.files.js { %>
  <script src="<%= src %>"
    integrity="<%= htmlRspackPlugin.files.jsIntegrity[index] %>"
    crossorigin="<%= rspackConfig.output.crossOriginLoading %>"
  ></script>
<% } %>

<% for _ in htmlRspackPlugin.files.css { %>
  <link href="<%= htmlRspackPlugin.files.css[index] %>"
    integrity="<%= htmlRspackPlugin.files.cssIntegrity[index] %>"
    crossorigin="<%= rspackConfig.output.crossOriginLoading %>"
    rel="stylesheet"
  />
<% } %>

With html-webpack-plugin, you can inject them like this:

index.ejs
<% for (let index in htmlWebpackPlugin.files.js) { %>
  <script
    src="<%= htmlWebpackPlugin.files.js[index] %>"
    integrity="<%= htmlWebpackPlugin.files.jsIntegrity[index] %>"
    crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
  ></script>
<% } %>

<% for (let index in htmlWebpackPlugin.files.css) { %>
  <link
    rel="stylesheet"
    href="<%= htmlWebpackPlugin.files.css[index] %>"
    integrity="<%= htmlWebpackPlugin.files.cssIntegrity[index] %>"
    crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
  />
<% } %>

Without HTML Plugin

The integrity can also be obtained from stats.assets. For example:

compiler.plugin('done', stats => {
  const integrityValues = stats
    .toJson()
    .assets.map(asset => [asset.name, asset.integrity]);
});
TIP

Note that when you add the integrity attribute on your link and script tags, you're also required to set the crossorigin attribute. It is recommended to set this attribute to the same value as the Rspack output.crossOriginLoading configuration option.

Options

hashFuncNames

  • Type: Array<"sha256" | "sha384" | "sha512">
  • Default: ["sha384"]

An array of strings, each specifying the name of a hash function to be used for calculating integrity hash values. Only supports sha256, sha384, and sha512 yet.

See SRI: Cryptographic hash functions for more details.

enabled

  • Type: "auto" | boolean

  • Default: "auto"

  • auto is the default value, which means the plugin is enabled when Rspack mode is production or none, and disabled when it is development.

  • true means the plugin is enabled in any mode.

  • false means the plugin is disabled in any mode.

htmlPlugin

  • Type: string
  • Default: "HtmlRspackPlugin"

The path to the HTML plugin, defaults to "HtmlRspackPlugin" which means the native HTML plugin of Rspack. If you are using the html-webpack-plugin, you can set this option to the path of it. It is recommended to set the absolute path to make sure the plugin can be found.

More Information

You can find more information about Subresource Integrity in the following resources: