Subresource Integrity (SRI) используется для проверки целостности загружаемых ресурсов, подключаемых через CDN или внешние источники. Механизм позволяет браузеру сравнить криптографический хеш загруженного файла с заранее вычисленным значением. При несовпадении ресурс блокируется, что предотвращает выполнение потенциально изменённого или скомпрометированного кода.
В экосистеме Webpack поддержка SRI реализуется через плагины, наиболее распространённый из которых — SriPlugin. Он интегрируется в процесс сборки и автоматически добавляет атрибуты integrity и crossorigin в HTML-выход, обычно совместно с HtmlWebpackPlugin.
SRI основан на вычислении хеша содержимого ресурса с использованием криптографических алгоритмов (SHA-256, SHA-384, SHA-512). Итоговое значение кодируется в base64 и помещается в HTML-разметку:
<script
src="https://cdn.example.com/app.js"
integrity="sha384-Base64EncodedHash"
crossorigin="anonymous">
</script>
При загрузке браузер:
Webpack сам по себе не управляет HTML-разметкой, однако через плагины может:
Основная задача SriPlugin — автоматизация вычисления SRI для всех выходных ассетов, подключаемых через HTML-шаблоны.
SriPlugin работает на этапе генерации HTML после завершения сборки Webpack:
Типичная интеграция происходит вместе с HtmlWebpackPlugin.
SriPlugin подключается как обычный Webpack-плагин:
npm install sri-webpack-plugin --save-dev
Конфигурация Webpack:
const HtmlWebpackPlugin = require('html-webpack-plugin');
const SriPlugin = require('sri-webpack-plugin');
module.exports = {
output: {
filename: '[name].[contenthash].js',
publicPath: 'https://cdn.example.com/'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new SriPlugin({
hashFuncNames: ['sha384'],
enabled: true
})
]
};
SriPlugin модифицирует HTML, уже сформированный HtmlWebpackPlugin. Последовательность выполнения критична:
<script>
и <link>.Результат:
<script
src="main.8d31f.js"
integrity="sha384-2n4kQx...Q0="
crossorigin="anonymous">
</script>
SriPlugin обрабатывает:
<script>)<link rel="stylesheet">)Пример CSS:
<link
href="styles.3f91c.css"
rel="stylesheet"
integrity="sha384-AbC123..."
crossorigin="anonymous">
Поддерживаются стандартные алгоритмы Web Crypto API:
Конфигурация:
new SriPlugin({
hashFuncNames: ['sha384', 'sha512']
});
При указании нескольких алгоритмов генерируются несколько значений integrity:
integrity="sha384-... sha512-..."
SRI тесно связан с стратегией кеширования Webpack:
[contenthash] обеспечивает уникальность файла при
изменении содержимого;Комбинация обеспечивает двойную защиту:
При использовании CDN SRI становится критически важным. Типичная схема:
Пример конфигурации:
output: {
publicPath: 'https://cdn.example.com/assets/'
}
SriPlugin автоматически подставляет integrity для всех ресурсов, загруженных через CDN.
Несмотря на автоматизацию, SRI имеет ряд особенностей:
Без корректного crossorigin браузер может игнорировать
SRI:
<script src="app.js" integrity="..." crossorigin="anonymous"></script>
Любая постобработка CDN (minify, inject banner) делает хеш недействительным.
При раздельной публикации HTML и JS возможна рассинхронизация:
new SriPlugin({
enabled: process.env.NODE_ENV === 'production'
});
new SriPlugin({
hashFuncNames: ['sha384'],
assetMatch: /\.(js|css)$/
});
Некоторые версии плагина позволяют расширять HTML-атрибуты:
new SriPlugin({
crossorigin: 'anonymous'
});
SRI часто используется совместно с CSP:
Content-Security-Policy: script-src 'self' https://cdn.example.com; style-src 'self' https://cdn.example.com;
Сценарий защиты:
Комбинация снижает риск подмены CDN.
SriPlugin использует потоковое чтение ассетов из compilation:
compilation.assets;Псевдологика:
const hash = crypto
.createHash('sha384')
.update(assetSource)
.digest('base64');
При multi-page приложениях:
new HtmlWebpackPlugin({
filename: 'admin.html',
chunks: ['admin']
}),
new HtmlWebpackPlugin({
filename: 'app.html',
chunks: ['app']
}),
new SriPlugin()
SriPlugin обрабатывает каждый HTML отдельно, сохраняя соответствие чанков.
Влияние на сборку:
Обычно накладные расходы минимальны, но при большом количестве ассетов (сотни файлов) возможен рост времени генерации HTML.
Помимо SriPlugin используются:
Однако автоматизация через SriPlugin остаётся наиболее стабильным решением в Webpack-пайплайне.
SriPlugin работает поверх стандартных API Webpack 4 и Webpack 5:
В Webpack 5 предпочтительно использование современных плагинов, поддерживающих async hooks.
Процесс можно описать как последовательность:
Эта цепочка обеспечивает контроль целостности на уровне доставки фронтенд-ресурсов и делает возможным безопасное использование CDN без потери доверия к содержимому.