Настройка 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))


