Subresource Integrity (SRI): защита CDN-скриптов
Subresource Integrity (SRI): защита CDN-скриптов
Subresource Integrity (SRI) — атрибут integrity на тегах <script> и <link>, который заставляет браузер сверить SHA-256/384/512-хеш загруженного файла с ожидаемым. Если хеш не совпадает — скрипт не выполнится. SRI защищает от сценария «взломали CDN → залили троян → все клиенты скомпрометированы», реальный инцидент с event-stream и Magecart.
Как работает SRI
Стандарт описан в W3C Subresource Integrity. Пример:
<script
src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"
integrity="sha384-1H217gwSVyLSIfaLxHbE7dRb3v4mYCKbpQvzx0cegeju1MVsGrX5xXxAvs/HgeFs"
crossorigin="anonymous"></script>
Браузер: 1) скачивает файл, 2) считает SHA-384, 3) сверяет с integrity, 4) если хеш не совпал — блокирует и пишет ошибку в консоль.
Когда применять
- CDN-скрипты (jQuery, Bootstrap, React) — особенно с jsdelivr, cdnjs, unpkg
- Сторонние шрифты, если критична целостность
- Виджеты аналитики/чатов с фиксированной версией
Не применяйте к динамическим скриптам с автообновлением — при каждом релизе ломается integrity.
Генерация хеша
curl -s https://cdn.example.com/file.js | openssl dgst -sha384 -binary | openssl base64 -A
Или онлайн-сервисы: srihash.org. Для версионированных CDN (jsdelivr, cdnjs) хеши уже доступны в интерфейсе.
crossorigin="anonymous"
Без этого атрибута браузер не даст JS-коду на вашей странице читать ошибку SRI — и загрузка cross-origin без CORS-заголовков заблокируется. Всегда добавляйте crossorigin="anonymous" для SRI.
CSP require-sri-for
Директива CSP Level 3 принудительно включает SRI для всех скриптов и стилей:
Content-Security-Policy: require-sri-for script style
Статус — экспериментальный, поддерживается не везде. Используйте как defence-in-depth.
SRI + versioning
Проблема: jsdelivr.net/jquery@latest обновляется — и integrity перестаёт совпадать. Решение:
- Фиксируйте версию:
jquery@3.7.1 - Автоматизируйте update integrity через CI (npm audit, yarn, Vite SRI plugin)
- Или — проксируйте скрипт через свой nginx с кэшем
SRI для собственного CDN
Если CDN ваш (CloudFront, Yandex Cloud CDN), SRI защищает от компрометации именно CDN-инфры (украли ключи S3 → подменили файл). Включайте integrity даже для своих ассетов в критичных потоках (checkout, auth).
Webpack / Vite
// webpack
const SubresourceIntegrityPlugin = require('webpack-subresource-integrity').SubresourceIntegrityPlugin;
module.exports = {
output: { crossOriginLoading: 'anonymous' },
plugins: [ new SubresourceIntegrityPlugin({ hashFuncNames: ['sha384'] }) ],
};
// Vite
import { sriPlugin } from 'vite-plugin-sri';
export default { plugins: [sriPlugin()] };
Проверка
Chrome DevTools → Network → щёлкните скрипт → Headers → посмотрите запрос + ответ. Если integrity не прошёл — консоль покажет «Failed to find a valid digest in the 'integrity' attribute».
Security Scanner enterno.io покажет все внешние скрипты на странице и отсутствие integrity — ценная информация для аудита.
FAQ
Нужен ли SRI для своего домена? Технически нет — same-origin скрипты доверены. Но если у вас один CDN на несколько проектов, SRI даёт изоляцию.
SHA-256 или SHA-384? SHA-384 рекомендуется W3C как текущий стандарт. Можно указать несколько: integrity="sha256-... sha384-...".
Что со стилями? SRI работает для <link rel="stylesheet"> аналогично.
SRI замедляет загрузку? Микросекундный overhead на подсчёт хеша. На practical load times не влияет.
Вывод
Для каждого CDN-скрипта на сайте — integrity + crossorigin="anonymous". Автоматизируйте через CI, мониторьте CDN-файлы через enterno monitoring. Связанное: HTTP Security Headers, CSP Setup.
Проверьте ваш сайт прямо сейчас
Проверить →