Skip to content
← Все статьи

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) если хеш не совпал — блокирует и пишет ошибку в консоль.

Когда применять

Не применяйте к динамическим скриптам с автообновлением — при каждом релизе ломается 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 перестаёт совпадать. Решение:

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.

Проверьте ваш сайт прямо сейчас

Проверить →
Другие статьи: SEC
SEC
Защита от Clickjacking: X-Frame-Options vs frame-ancestors
15.04.2026 · 6 просм.
SEC
WAF (Web Application Firewall): базовый гайд
15.04.2026 · 6 просм.
SEC
Защита от XSS атак: типы, эскейпинг, CSP, Trusted Types
15.04.2026 · 3 просм.
SEC
API Rate Limiting: token bucket, 429, Retry-After
15.04.2026 · 4 просм.