Как защитить сайт с SRI: пошаговое внедрение хеш-атрибутов
#Веб-безопасностьДля кого эта статья:
- Разработчики веб-приложений
- Специалисты по веб-безопасности
- Администраторы и технические руководители веб-сайтов
Представьте: ваш сайт внезапно начинает красть данные пользователей. Не потому что вас взломали напрямую, а потому что CDN, с которого вы загружаете jQuery, был скомпрометирован. Звучит как кошмар? Именно такие атаки предотвращает SRI — технология, позволяющая гарантировать неизменность загружаемых ресурсов с помощью криптографических хешей. В 2022 году было зафиксировано свыше 300 000 атак с использованием подмены JavaScript-файлов. Внедрение Subresource Integrity становится не просто рекомендацией, а необходимостью для тех, кто серьезно относится к безопасности своего веб-ресурса. 🛡️
Что такое SRI и зачем нужна защита веб-ресурсов
Subresource Integrity (SRI) — механизм безопасности, позволяющий браузеру проверять, что загружаемые с внешних источников ресурсы (JavaScript, CSS) не были подменены или модифицированы. Суть технологии заключается в добавлении криптографических хешей к тегам <script> и <link>, что гарантирует загрузку только валидных, неизмененных файлов.
SRI решает фундаментальную проблему современной веб-разработки: как использовать сторонние ресурсы, не подвергая пользователей риску? Большинство сайтов загружает скрипты с CDN (Content Delivery Networks), что увеличивает скорость загрузки, но создает потенциальную уязвимость.
Сергей Ковалев, руководитель отдела веб-безопасности
Мой клиент, крупный финансовый портал, столкнулся с атакой через подмену jQuery на CDN. Злоумышленники модифицировали библиотеку так, что она собирала данные банковских карт и отправляла на сторонний сервер. Посетители ни о чем не подозревали — сайт работал как обычно. Проблему обнаружили только через неделю, когда пользователи начали сообщать о подозрительных транзакциях. Внедрение SRI заняло всего час работы, но полностью исключило возможность повторения инцидента. Теперь любая попытка загрузить модифицированную библиотеку автоматически блокируется браузером.
Риски отсутствия SRI-защиты включают:
- Атаки на цепочку поставок — когда взламывается не ваш сайт, а источник ваших зависимостей
- Man-in-the-middle атаки — перехват и модификация ресурсов при передаче
- Компрометация CDN — взлом серверов доставки контента
- Внедрение вредоносного кода — включая скиммеры кредитных карт, майнеры криптовалют и трояны
| Тип уязвимости | Метод атаки | Защита через SRI |
|---|---|---|
| Атака на CDN | Изменение файлов на серверах CDN | Полная (браузер блокирует измененные файлы) |
| DNS-спуфинг | Перенаправление на поддельный сервер | Полная (контент не соответствует хешу) |
| MITM-атаки | Перехват и модификация трафика | Полная (измененный контент отклоняется) |
| Локальные модификации | Вредоносное ПО на клиенте | Ограниченная (зависит от браузера) |
Критически важные сценарии применения SRI:
- Финансовые сервисы, работающие с платежными формами
- Системы с аутентификацией и обработкой конфиденциальных данных
- Корпоративные порталы и интранет-системы
- Сайты электронной коммерции с функциями корзины и оформления заказа
- Любые ресурсы, загружающие скрипты и стили из внешних источников

Принципы работы Subresource Integrity в веб-безопасности
SRI функционирует на основе криптографических хешей — уникальных "отпечатков" файлов. Любое, даже минимальное изменение содержимого приводит к полному изменению хеша. Процесс проверки целостности происходит на стороне браузера и включает следующие этапы:
- Браузер получает HTML-документ с тегами, содержащими атрибут
integrity - При обнаружении тега с внешним ресурсом и атрибутом
integrity, браузер запрашивает файл - После загрузки файла браузер вычисляет его хеш-сумму
- Полученный хеш сравнивается с указанным в атрибуте
integrity - При совпадении хешей ресурс используется, при несовпадении — блокируется
SRI поддерживает несколько алгоритмов хеширования, различающихся по уровню безопасности и производительности:
| Алгоритм | Длина хеша | Уровень защиты | Рекомендации по применению |
|---|---|---|---|
| SHA-256 | 256 бит | Высокий | Стандартный выбор для большинства случаев |
| SHA-384 | 384 бит | Очень высокий | Для критически важных ресурсов |
| SHA-512 | 512 бит | Максимальный | Для особо чувствительных систем |
Для полноценной работы SRI требуется соблюдение нескольких условий:
- Ресурс должен загружаться по HTTPS (для предотвращения MITM-атак)
- Оба домена (основной и домен ресурса) должны использовать защищенное соединение
- При использовании атрибута
integrityрекомендуется также добавлять атрибутcrossorigin="anonymous" - Браузер должен поддерживать SRI (все современные браузеры поддерживают)
Важно понимать, что SRI не заменяет другие меры безопасности, а дополняет их. В частности, SRI не защищает от:
- XSS-атак в вашем собственном коде
- Уязвимостей в легитимных скриптах (даже если их целостность подтверждена)
- Атак на саму инфраструктуру вашего сервера
Максим Петров, технический директор
Когда мы внедряли SRI на крупном новостном портале, столкнулись с неожиданной проблемой. Наши аналитики заметили резкое падение числа загрузок скриптов. Расследование показало, что CDN, который мы использовали для jQuery, начал автоматически обновлять библиотеку до новейшей патч-версии. Хеши не совпадали, и браузеры блокировали загрузку. Это выявило интересный побочный эффект SRI: он не только защищает от атак, но и фактически "замораживает" версии используемых библиотек. Мы модифицировали процесс деплоя, добавив автоматический пересчет хешей при обновлении зависимостей. После этого система стала не только безопасной, но и более предсказуемой — никаких "сюрпризов" с внезапными обновлениями библиотек.
Генерация хеш-атрибутов для файлов CSS и JavaScript
Для внедрения SRI первым шагом является генерация криптографических хешей для внешних ресурсов. Существует несколько способов получения хешей, от ручных методов до автоматизированных решений. 🔐
Рассмотрим основные методы генерации хеш-атрибутов:
- Использование командной строки (OpenSSL, встроенные утилиты Linux/macOS)
- Онлайн-генераторы SRI-хешей
- Инструменты сборки (webpack, gulp и др.)
- Серверные скрипты на PHP, Node.js и других языках
Для генерации хеша с помощью OpenSSL выполните следующие шаги:
- Скачайте файл, для которого требуется создать хеш
- Используйте команду OpenSSL для генерации base64-кодированного хеша
Пример команды для генерации SHA-384 хеша:
cat filename.js | openssl dgst -sha384 -binary | openssl base64 -A
Для SHA-256:
cat filename.js | openssl dgst -sha256 -binary | openssl base64 -A
В Windows через PowerShell процесс выглядит так:
Get-FileHash -Algorithm SHA384 -Path filename.js | Select-Object Hash | ForEach-Object { [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_.Hash)) }
Автоматизация генерации хешей при сборке проекта значительно упрощает процесс. Для webpack существует специальный плагин webpack-subresource-integrity:
- Установите плагин:
npm install webpack-subresource-integrity --save-dev - Добавьте в конфигурацию webpack:
const SriPlugin = require('webpack-subresource-integrity');
module.exports = {
output: {
crossOriginLoading: 'anonymous'
},
plugins: [
new SriPlugin({
hashFuncNames: ['sha384'],
enabled: process.env.NODE_ENV === 'production'
})
]
};
Для динамической генерации хешей на сервере можно использовать следующие решения:
Node.js пример:
const crypto = require('crypto');
const fs = require('fs');
function generateSriHash(filePath, algorithm = 'sha384') {
const fileBuffer = fs.readFileSync(filePath);
const hashSum = crypto.createHash(algorithm);
hashSum.update(fileBuffer);
return algorithm + '-' + hashSum.digest('base64');
}
PHP пример:
function generateSriHash($filePath, $algorithm = 'sha384') {
$fileContent = file_get_contents($filePath);
$hash = hash($algorithm, $fileContent, true);
return $algorithm . '-' . base64_encode($hash);
}
Важные рекомендации при генерации хешей:
- Используйте как минимум SHA-256 для обеспечения достаточного уровня безопасности
- Для критически важных ресурсов предпочтительнее SHA-384
- Генерируйте хеши заново при любом изменении файла
- Сохраняйте хеши для быстрого доступа в процессе разработки
- Автоматизируйте процесс в производственной среде
Для работы с несколькими алгоритмами хеширования можно указывать несколько хешей через пробел:
integrity="sha256-hash1 sha384-hash2"
Такой подход обеспечивает совместимость с различными браузерами и позволяет сделать плавный переход на более стойкие алгоритмы в будущем.
Интеграция атрибутов integrity в HTML-код сайта
После генерации хешей необходимо интегрировать их в HTML-код сайта, добавив атрибуты integrity к тегам <script> и <link>. Правильная реализация SRI требует соблюдения определённых правил и понимания нюансов работы с внешними ресурсами. 📝
Базовый синтаксис внедрения SRI выглядит следующим образом:
Для JavaScript-файлов:
<script src="https://cdn.example.com/script.js" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous"></script>
Для CSS-файлов:
<link rel="stylesheet" href="https://cdn.example.com/styles.css" integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC" crossorigin="anonymous">
Атрибут crossorigin является обязательным для корректной работы SRI. Он указывает, как браузер должен обрабатывать запросы CORS (Cross-Origin Resource Sharing). Для SRI используется значение anonymous, что означает отправку запроса без учетных данных.
Примеры интеграции для популярных библиотек:
<!-- jQuery с SRI -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK" crossorigin="anonymous"></script>
<!-- Bootstrap CSS с SRI -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
Большинство популярных CDN, включая jsDelivr, CDNJS и unpkg, предоставляют готовые хеши SRI для своих ресурсов. Например, на странице библиотеки на CDNJS можно найти кнопку "Copy SRI", которая копирует полный HTML-тег с атрибутом integrity.
Особенности работы с различными типами ресурсов:
| Тип ресурса | Особенности интеграции SRI | Возможные проблемы |
|---|---|---|
| Статические JS библиотеки | Проста интеграция с фиксированным хешем | Несовместимость при обновлении библиотеки |
| CSS фреймворки | Требует пересчета хеша при изменении темы | Динамически генерируемые стили не проверяются |
| Динамические ресурсы | Сложность в автоматизации обновления хешей | Частые изменения требуют механизма автообновления |
| Собственные ресурсы | Необходимость интеграции в процесс сборки | Дополнительные этапы в CI/CD pipeline |
Важные рекомендации при интеграции SRI:
- Используйте SRI только для статических ресурсов, которые не меняются часто
- Внедряйте механизм автоматического обновления хешей при изменении ресурсов
- Помните, что ресурсы с неверным хешем не будут загружены браузером
- Применяйте SRI в первую очередь для критически важных ресурсов (авторизация, платежи)
- Контролируйте переход на HTTPS для всех подключаемых ресурсов
Для многостраничных сайтов целесообразно централизовать хранение хешей, например, в конфигурационном файле или базе данных, чтобы избежать дублирования и упростить обновление.
Интеграция SRI с системами управления контентом (CMS):
- WordPress: используйте хуки
script_loader_tagиstyle_loader_tagдля модификации тегов - Drupal: создайте модуль, расширяющий функциональность Asset API
- Joomla: используйте плагины для фильтрации вывода HTML
Пример WordPress-функции для добавления атрибутов integrity:
function add_sri_to_scripts($tag, $handle, $src) {
// Массив с хешами для известных ресурсов
$integrity_hashes = [
'jquery-core' => 'sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK',
'bootstrap' => 'sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13'
];
if (isset($integrity_hashes[$handle])) {
$tag = str_replace(' src=', ' integrity="' . $integrity_hashes[$handle] . '" crossorigin="anonymous" src=', $tag);
}
return $tag;
}
Тестирование и мониторинг SRI-защиты веб-проекта
После внедрения SRI критически важно провести тщательное тестирование и настроить регулярный мониторинг. Это гарантирует не только правильную работу защиты, но и позволит избежать проблем с доступностью контента. 🔍
Для тестирования SRI-имплементации существует несколько эффективных методов:
- Ручное тестирование на различных браузерах и устройствах
- Автоматизированное тестирование с использованием инструментов веб-безопасности
- Симуляция атак для проверки эффективности защиты
- Мониторинг производительности для отслеживания влияния SRI на скорость загрузки
Пошаговый процесс тестирования SRI:
- Проверьте корректность загрузки ресурсов с валидными хешами
- Намеренно измените хеш для одного из ресурсов и убедитесь, что браузер блокирует его загрузку
- Проверьте консоль разработчика на наличие ошибок связанных с SRI
- Протестируйте поведение сайта при блокировке критических ресурсов
- Оцените влияние SRI на время загрузки страницы
Для симуляции атак и проверки эффективности SRI можно использовать локальные прокси, такие как OWASP ZAP или Burp Suite, которые позволяют модифицировать контент "на лету".
Типичные ошибки, связанные с SRI, и их решения:
| Проблема | Симптомы | Решение |
|---|---|---|
| Неверный хеш | Ресурс не загружается, ошибка в консоли | Перегенерировать хеш для текущей версии файла |
| Отсутствие атрибута crossorigin | SRI не работает для кросс-доменных ресурсов | Добавить атрибут crossorigin="anonymous" |
| Динамически обновляемые ресурсы | Периодические сбои при обновлении CDN | Автоматизировать обновление хешей, использовать версионированные URL |
| Несовместимость с некоторыми CDN | Проблемы с заголовками CORS | Переключиться на CDN с полной поддержкой SRI |
Для постоянного мониторинга SRI рекомендуется:
- Настроить оповещения о блокировках ресурсов через системы мониторинга фронтенда (Sentry, LogRocket)
- Включить логирование ошибок SRI на стороне клиента с отправкой отчетов
- Регулярно проверять совпадение хешей с актуальными версиями используемых библиотек
- Отслеживать изменения в CDN-политиках поставщиков контента
- Интегрировать проверку SRI в процессы CI/CD
Для автоматизации проверки SRI можно использовать скрипт, который сравнивает текущие хеши файлов с указанными в HTML:
// Пример Node.js скрипта для проверки SRI хешей
const cheerio = require('cheerio');
const axios = require('axios');
const crypto = require('crypto');
async function verifySRI(url) {
try {
const response = await axios.get(url);
const $ = cheerio.load(response.data);
const promises = [];
$('script[integrity], link[integrity]').each(function() {
const element = $(this);
const resourceUrl = element.attr('src') || element.attr('href');
const integrity = element.attr('integrity');
promises.push(checkResourceIntegrity(resourceUrl, integrity));
});
return Promise.all(promises);
} catch (error) {
console.error('Error verifying SRI:', error);
}
}
async function checkResourceIntegrity(url, integrityAttr) {
// Реализация проверки соответствия ресурса хешу
}
Важные рекомендации по мониторингу SRI в долгосрочной перспективе:
- Внедрите процедуру ревизии внешних зависимостей, обновляя хеши при каждом обновлении
- Создайте резервный план на случай недоступности CDN
- Документируйте все изменения, связанные с SRI, для облегчения отладки в будущем
- Обучите команду разработки правильной работе с SRI и процедурам обновления
- Рассмотрите внедрение CSP (Content Security Policy) как дополнительного уровня защиты
Регулярный пентест с фокусом на возможные атаки через скрипты и стили должен стать частью общей стратегии безопасности сайта. Профессиональное тестирование на проникновение поможет выявить уязвимости, которые могут остаться незамеченными при стандартном тестировании.
SRI-защита стала стандартом де-факто для всех серьезных веб-проектов, требующих высокого уровня безопасности. Комбинация криптографической верификации ресурсов с правильно настроенным мониторингом создает надежный барьер против множества распространенных векторов атак. Однако помните, что SRI — это только компонент комплексной стратегии безопасности. Без правильного внедрения HTTPS, CSP и других механизмов защиты, даже самая лучшая SRI-имплементация оставляет пространство для уязвимостей. Постоянное внимание к деталям и понимание принципов работы веб-технологий — ключи к по-настоящему защищенному веб-ресурсу.
Элина Баранова
разработчик Android