Настройка SRI (Subresource Integrity) — это механизм защиты целостности внешних ресурсов. Он позволяет браузеру проверять, что загруженный файл не был изменен злоумышленником после публикации на стороннем сервере. Это критически важно при использовании CDN, библиотек с открытым кодом или аналитических скриптов.

Что такое SRI и зачем он нужен

SRI (Subresource Integrity) — это механизм безопасности, встроенный в современные браузеры. Он работает по принципу цифровой подписи: вы генерируете уникальный хеш для файла и указываете его в атрибуте integrity тега.

paragraphs2

Когда сторонний ресурс (например, библиотека jQuery или скрипт аналитики) попадает под атаку, злоумышленник может изменить содержимое файла. Без SRI браузер скачает и выполнит измененный код. С включенным SRI браузер вычисляет хеш полученного файла на лету и сравнивает его с указанным в коде. Если значения не совпадают — загрузка блокируется.

paragraphs3

Это защита от подмены контента (content tampering). Она не предотвращает взлом вашего сервера, но делает невозможным использование ваших ресурсов для доставки вредоносного кода через компрометированные внешние источники.

examples1

Условный пример: вы подключаете скрипт с CDN. Хакер получает доступ к серверу CDN и меняет код в файле script.js на код, который крадет куки.

examples2

Без SRI: браузер загружает измененный файл и выполняет его.

examples3

С SRI: браузер видит, что хеш изменился, выводит ошибку в консоль и не запускает скрипт. Пользователь не теряет данные.

limitations1

SRI применим только к внешним ресурсам (cross-origin). Для локальных файлов он бесполезен, так как браузер сравнивает хеш с тем, что лежит на вашем же диске.

limitations2

Метод защищает от подмены содержимого, но не от XSS-атак, если злоумышленник уже имеет возможность заставить пользователя выполнить код (например, через фишинг или уязвимость в самом браузере).

limitations3

Если ресурс обновляется часто, вам придется регулярно пересчитывать хеши и обновлять код. Это накладывает операционную нагрузку.

steps1

Шаг 1: Определите список внешних ресурсов. Обычно это теги <script>, <link> (CSS) и <img>.

steps2

Шаг 2: Скачайте исходный файл на локальный компьютер или используйте инструмент командной строки для генерации хеша.

steps3

Шаг 3: Вычислите хеш файла с помощью утилиты типа sha256sum (Linux/Mac) или PowerShell (Windows).

steps4

Генерация хешей и их форматирование

Хеш должен быть представлен в формате base64. Стандартный вывод командной строки часто дает hex-формат, который нужно преобразовать.

paragraphs2

Пример для Linux/Mac:

paragraphs3

sha256sum файл.js | awk '{print $1}' | xxd -r -p | base64

paragraphs4

Пример для Windows (PowerShell):

paragraphs5

$hash = Get-FileHash "file.js" -Algorithm SHA256; [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($hash.Hash))

paragraphs6

Полученная строка вставляется в атрибут integrity.

paragraphs7

Пример тега: <script src="https://cdn.example.com/lib.js" integrity="sha384-abc123…">

paragraphs8

Важно: хеш чувствителен к пробелам и переносам строк. Файл должен быть скачан точно в том виде, в котором он будет загружаться браузером (без лишних комментариев или отступов, если они влияют на размер).

paragraphs9

Для CSS аналогично используется атрибут integrity в теге <link>.

tools1

Используйте готовые инструменты генерации хешей для CDN. Многие провайдеры (Cloudflare, jsDelivr) предоставляют готовый атрибут integrity в метаданных или документации.

tools2

Не используйте онлайн-генераторы хешей для чувствительных данных — передавайте файл локально.

steps1

Шаг 1: Выберите алгоритм. Рекомендуется SHA-256 как баланс между безопасностью и производительностью.

steps2

Выбор алгоритма хеширования

SHA-256 является стандартом де-факто для SRI. Он обеспечивает достаточную стойкость против коллизий при приемлемой скорости вычисления.

paragraphs2

SHA-384 и SHA-512 обеспечивают более высокий уровень защиты, но требуют больше вычислительных ресурсов. Для большинства веб-ресурсов это избыточно.

paragraphs3

MD5 и SHA-1 считаются небезопасными для целей SRI из-за известных уязвимостей к коллизиям. Их использование не рекомендуется.

paragraphs4

Если вы используете очень большие файлы (например, тяжелые библиотеки), разница в производительности между SHA-256 и SHA-512 будет минимальна на стороне клиента, но безопасность возрастает.

paragraphs5

Рекомендация: используйте SHA-256 для всех внешних ресурсов. Переходите на более стойкие алгоритмы только при наличии конкретных угроз или требований регуляторов.

examples1

Пример использования SHA-256: integrity="sha256-xyz…"

examples2

Пример использования SHA-384 (редко): integrity="sha384-abc…"

examples3

Избегайте MD5: integrity="md5-def…" — это устаревшая и небезопасная практика.

limitations1

Алгоритм не влияет на размер атрибута значительно. Разница в длине строки между SHA-256 и SHA-512 составляет несколько байт.

limitations2

Производительность браузера при проверке хешей пренебрежимо мала по сравнению с временем загрузки самого ресурса.

steps1

Шаг 1: Оцените размер файла. Для файлов до 10 МБ разница в скорости между SHA-256 и SHA-512 незаметна.

steps2

Практические примеры реализации

HTML с внешним скриптом:

paragraphs2

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js" integrity="sha384-…" crossorigin="anonymous"></script>

paragraphs3

CSS из внешнего файла:

paragraphs4

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto" integrity="sha384-…" crossorigin="anonymous">

paragraphs5

JavaScript с динамической загрузкой (fetch):

paragraphs6

fetch('https://example.com/script.js', { integrity: 'sha384-…', credentials: 'same-origin' }).then(res => res.text()).then(code => eval(code));

paragraphs7

Обратите внимание: атрибут integrity не поддерживается в теге <img> для проверки целостности изображения, но может использоваться для блокировки загрузки при несоответствии.

paragraphs8

Для SVG и шрифтов также работает механизм SRI через атрибут integrity.

examples1

Условный пример: вы подключаете карту Google Maps. В документации Google указан хеш.

examples2

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_KEY" integrity="sha384-…" crossorigin></script>

examples3

Если хеш не совпадает, карта не загрузится, и в консоли появится ошибка: Refused to load the script '…' because its integrity checksum failed.

errors1

Ошибка 403 или 404 при проверке хеша означает, что файл не найден или запрещен. SRI не влияет на статус-коды.

errors2

Ошибки при настройке SRI

Неверный формат хеша. Хеш должен быть в base64. Если вы скопировали hex-строку без преобразования, браузер выдаст ошибку.

paragraphs2

Пропущен атрибут crossorigin. Для внешних ресурсов рекомендуется добавлять crossorigin="anonymous" или crossorigin="use-credentials". Без этого атрибута некоторые браузеры могут игнорировать SRI при загрузке из других доменов.

paragraphs3

Изменение содержимого файла после генерации хеша. Если вы скачали файл, а затем изменили его (добавили пробелы, комментарии), хеш перестанет совпадать.

paragraphs4

Использование устаревших алгоритмов. MD5 и SHA-1 не рекомендуются для SRI из-за риска коллизий.

paragraphs5

Отсутствие проверки в консоли. После добавления атрибута integrity обязательно проверьте работу ресурса в DevTools (F12 -> Console). Там будут отображаться ошибки несоответствия хешей.

paragraphs6

Пример ошибки в консоли: Refused to load the script 'https://…' because its integrity checksum failed verification.

paragraphs7

Решение: перескачайте файл, сгенерируйте новый хеш и обновите код.

paragraphs8

Игнорирование обновления ресурсов. Если библиотека обновилась, старый хеш больше не подойдет. Нужно регулярно мониторить обновления зависимостей.

limitations1

SRI не защищает от атак на уровне DNS или MITM (Man-in-the-Middle), если злоумышленник может подменить сам URL.

limitations2

Ограничения метода

SRI работает только для ресурсов, загружаемых через HTTP/HTTPS. Для протоколов FTP, file:// он не применим.

paragraphs2

Метод не защищает от XSS, если злоумышленник может внедрить код через другие векторы (например, через форму или уязвимость в CMS).

paragraphs3

Для внутренних ресурсов (локальные файлы) SRI не нужен и не поддерживается.

paragraphs4

Если ресурс загружается асинхронно через fetch без указания integrity, защита не сработает.

paragraphs5

SRI не заменяет HTTPS. Он дополняет шифрование трафика проверкой целостности содержимого.

paragraphs6

При использовании CDN с автоматическим обновлением контента вам придется настроить процесс пересчета хешей при каждом обновлении.

paragraphs7

Некоторые старые браузеры (Internet Explorer) не поддерживают SRI. Для них нужно предусмотреть фоллбэк или убедиться, что целевая аудитория использует современные версии.

paragraphs8

SRI не защищает от атак на уровне приложения, если злоумышленник может изменить код на сервере до того, как он будет загружен браузером.

examples1

Условный пример: вы используете CDN с автоматическим обновлением. Хеш меняется каждый день. Вам нужно настроить скрипт для автоматического обновления атрибутов integrity.

examples2

Проверка корректности настройки

Откройте страницу в браузере и нажмите F12 для открытия DevTools.

paragraphs2

Перейдите во вкладку Console.

paragraphs3

Если хеш указан правильно, ошибок не будет. Если нет — появится сообщение о несоответствии.

paragraphs4

Используйте инструменты аудита безопасности, такие как Lighthouse или BuiltWith, чтобы проверить наличие SRI на странице.

paragraphs5

Можно также использовать онлайн-инструменты для проверки хешей, но лучше делать это локально.

paragraphs6

Для автоматической проверки можно написать скрипт, который сравнивает текущий хеш файла с тем, что указан в коде.

paragraphs7

Рекомендуется включить SRI постепенно: сначала для некритичных ресурсов (например, шрифты), затем для важных библиотек.

paragraphs8

После внедрения регулярно проверяйте консоль на наличие новых ошибок при обновлении зависимостей.

examples1

Условный пример: вы добавили SRI для библиотеки jQuery. В консоли нет ошибок — значит, настройка корректна.

examples2

Вопросы и ответы

Можно ли использовать SRI для локальных файлов?

Нет. SRI предназначен только для внешних ресурсов (cross-origin). Для локальных файлов он не нужен и не поддерживается браузерами.

Какой алгоритм хеширования лучше всего использовать?

Рекомендуется SHA-256 как баланс между безопасностью и производительностью. SHA-384 и SHA-512 избыточны для большинства задач, MD5 и SHA-1 небезопасны.

Что делать, если хеш не совпадает после обновления библиотеки?

Перескачайте файл, сгенерируйте новый хеш и обновите атрибут integrity в коде. Это нормальная практика при обновлении зависимостей.

Поддерживает ли SRI изображения?

Да, атрибут integrity можно использовать в тегах <img>, но он не будет проверять целостность изображения как такового, а только блокирует загрузку при несоответствии хеша.

Как часто нужно обновлять хеши?

Хеши нужно обновлять каждый раз, когда меняется содержимое внешнего ресурса. Рекомендуется настроить мониторинг зависимостей и автоматическое обновление атрибутов integrity.

sha256sum file.js | awk '{print $1}' | xxd -r -p | base64
$hash = Get-FileHash "file.js" -Algorithm SHA256; [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($hash.Hash))