Понимание целостности подресурсов


Понимание целостности подресурсов

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

Если вы когда-либо использовали версию библиотеки JavaScript, размещенную на CDN, вы, возможно, заметили странный вид integrity атрибут в теге скрипта. Этот атрибут содержит, казалось бы, бесконечный буквенно-цифровой мусор, который у вас может возникнуть соблазн удалить в поисках более чистого кода.

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

Немного истории

Давным-давно, когда JavaScript был гораздо более бедным родственником HTML и CSS, нам не нужно было слишком много думать о том, как наши скрипты могут быть использованы в качестве вектора атаки на наши веб-сайты. Большинство сайтов размещались на одном физическом сервере где-то в нашей собственной хостинговой инфраструктуре, и именно этот сервер мы думали о защите, когда речь шла о передовых методах обеспечения безопасности.

По мере того, как браузеры становились все более функциональными, а сетевые подключения становились все толще, мы стали использовать все больше и больше JavaScript, и, в конце концов, начали появляться многоразовые библиотеки JavaScript. В те первые дни такие библиотеки, как script.aculo.us, Prototype и, в конечном итоге, jQuery, начали получать признание среди разработчиков, стремящихся добавить больше интерактивности на свои страницы.

С этими добавленными библиотеками и последующими плагинами увеличился вес страницы, и вскоре мы начали серьезно думать о производительности внешнего интерфейса. Такие ресурсы, как сети доставки контента (CDN), которые ранее были резервом гигантских корпораций, стали обычным явлением для повседневного создания быстрых веб-сайтов.

Еще после прыжка! Продолжить чтение ниже ↓

Попутно какая-то светлая искра заметила, что все сайты запрашивают свои собственные копии общих библиотек — такие вещи, как последняя версия jQuery — и если бы существовала общая версия этих библиотек CDN, которую мог бы использовать каждый сайт, то пользователь не стал бы не нужно продолжать скачивать один и тот же файл. Они принимали удар за первый сайт, который использовал файл, но затем он оставался в их локальном кеше браузера, и загрузки для каждого последующего сайта могли быть пропущены. Гений!

Вот почему вы увидите ссылки CDN для ваших любимых библиотек, используя такие URL-адреса, как jsdelivr.com — они используют общий CDN для размещения файлов, чтобы их пользователи видели преимущества производительности.

Что может пойти не так?

Это остается хорошим практичным способом работы, но он создает потенциальный вектор для атаки. Давайте представим, что сейчас 2012 год, и все используют новый jQuery 1.8. Возвращаясь к традиционному способу ведения дел, у каждого будет свой собственный файл jQuery 1.8, размещенный как часть их собственного веб-сайта на их собственном сервере.

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

Но сейчас все не так, поскольку все используют jQuery, загружаемый с общего CDN. И когда я говорю всем, я не имею в виду сотни веб-страниц. Я имею в виду миллионы веб-страниц. Внезапно этот файл стал очень привлекательной целью для нашего теневого хакера. Если они смогут скомпрометировать этот единственный файл, они смогут очень быстро запустить код на миллионах веб-страниц по всему миру.

Неважно, что это за код. Это может быть розыгрыш для порчи страниц, это может быть код для кражи ваших паролей, это может быть код для майнинга криптовалюты, или это могут быть хитрые трекеры, которые следят за вами в Интернете и создают маркетинговый профиль. Важно то, что невинный файл, добавленный разработчиком на страницу, был изменен, и теперь у вас есть какой-то вредоносный JavaScript, работающий как часть вашего сайта. Это большая проблема.

Введите целостность подресурса

Вместо того, чтобы откатывать часы назад и отказываться от полезного способа использования кода, SRI — это решение, которое добавляет простой уровень безопасности. Что такое НИИ и integrity Атрибут гарантирует, что файл, который вы связали со страницей, никогда не изменится. И если он изменится, то браузер его отклонит.

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

Хеширование файлов — это процесс взятия файла и его обработки с помощью алгоритма, который сводит его к короткому строковому представлению, известному как хэш или контрольная сумма. Не вдаваясь в подробности, процесс либо повторяем, либо обратим, настолько, что если вы дадите кому-то файл вместе с хэшем, он сможет запустить тот же алгоритм, чтобы проверить, совпадают ли они. Если файл изменится или изменится хэш, совпадения больше не будет, и вы поймете, что что-то не так, и не должны доверять файлу.

При использовании SRI ваша веб-страница содержит хэш, а сервер (CDN или где-либо еще) содержит файл. Браузер загружает файл, затем быстро вычисляет, чтобы убедиться, что он совпадает с хэшем в integrity атрибут. Если он совпадает, то файл используется, а если нет, то блокируется.

Пробуем

Если я пойду в getbootstrap.com сегодня, чтобы получить ссылку CDN на версию Bootstrap, мне дали тег, который выглядит так:

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

Вы можете видеть, что src атрибут, как мы привыкли, и integrity Атрибут содержит то, что мы теперь знаем как хэш.

Хэш на самом деле состоит из двух частей. Первый — это префикс для объявления используемого алгоритма хеширования. В данном случае это sha384. Затем следует тире, а затем сам хеш, закодированный с помощью base64.

Вы можете быть знакомы с base64 как способ кодирования встроенных файлов, таких как изображения, в страницы. Это не криптографический процесс — это просто быстрый и удобный способ закодировать потенциально беспорядочные данные таким образом, чтобы они аккуратно транслировались в ASCII. Вот почему он так часто используется в Интернете.

Увидев это, браузер загрузит bootstrap.min.js. Перед его выполнением будет base64 расшифруйте хэш, а затем используйте sha384 алгоритм хеширования, чтобы подтвердить, что хэш соответствует только что загруженному файлу. Если он совпадает, файл выполняется.

Я могу проверить это, поместив этот тег на страницу, а затем перейдя на вкладку «Сеть» в инструментах браузера, чтобы увидеть, что файл был загружен.

Вкладка «Сеть»

(Большой превью)

я вижу bootstrap.min.js (а также необходимый файл jQuery) успешно загружены.

Давайте посмотрим, что произойдет, если я обновлю хеш, чтобы он стал чем-то, заведомо неверным.

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-SmashingMagazineIsCoolForCats" crossorigin="anonymous"></script>

хэш

(Большой превью)

Как видите, хэш, указанный на моей странице, больше не соответствует файлу, поэтому файл блокируется.

Использование SRI в ваших собственных проектах

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

Нетрудно представить сценарий, в котором хакеру удается получить доступ всего к нескольким файлам на вашем сайте. Я думаю, что большинство из нас видели клиента, коллегу или друга, у которого в какой-то момент был скомпрометирован сайт WordPress с кучей неприятного мусора, о котором они даже не подозревали.

SRI может защитить вас и от этого. Если вы создаете хэши целостности для своих собственных файлов, ваш сайт может отклонять любые изменения так же, как и для удаленно размещенного файла.

Генерация хэшей

Как и следовало ожидать, вы можете запустить некоторые команды на терминале вашего компьютера, чтобы сгенерировать хэш для файла. Этот пример того, как это сделать, взят из Целостность подресурсов MDN страница:

cat FILENAME.js | openssl dgst -sha384 -binary | openssl base64 -A  

Это получение содержимого FILENAME.js и передать его в качестве входных данных openssl создать дайджест с помощью sha384который затем передается в качестве входных данных в другой openssl приказать base64 закодировать результат. Это не только сложно и неясно, но и не то, что вы хотите делать вручную каждый раз, когда ваш файл JavaScript изменяется.

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

Если вы используете Gulp для создания своих сайтов, есть глоток-шри который выведет файл JSON со списком ваших файлов и их хэшей. Затем вы можете использовать это на своем сайте. Например, для динамически отображаемого сайта вы можете создать подключаемый модуль шаблона для чтения этого файла и добавления хэшей в свои шаблоны, где это необходимо.

Если вы все еще используете Gulp, но у вас есть статический сайт (или статически сгенерированный сайт), вы можете использовать глоток-шри-хэш который фактически будет проходить через ваши HTML-страницы и изменять страницы, добавляя хэши там, где это необходимо, что очень удобно.

Если вы используете Webpack, есть веб-страница-субресурс-целостность который в истинном стиле Webpack более сложен, чем любой человек может ожидать, но, похоже, работает.

Для тех, кто использует шаблонизатор Handlebars, доступные вам вариантыи если ваш процесс сборки представляет собой просто базовый JavaScript, есть простые решения там тоже.

Если вы используете CMS, например WordPress, я обнаружил плагин это, кажется, облегчает, хотя я сам не пробовал. Поиск в Google выбранной вами платформы с помощью SRI или Sub Resource Integrity, скорее всего, укажет вам правильное направление.

По сути, вы хотите подключить свое хеширование после ваши файлы JavaScript были минимизированы, а затем сделайте этот хэш каким-то образом доступным для любой части вашей системы, выводящей <script> теги. Одним из чудес веб-платформы является то, что она настолько разнообразна с технической точки зрения, что, к сожалению, не позволяет мне дать вам хорошие инструкции по реализации!

Другие вещи, которые следует отметить

В этой статье я много говорил о файлах JavaScript, поскольку именно в них наиболее целесообразно защищаться от хакерских атак. SRI также работает с CSS, так что вы можете использовать его там точно так же. Риск вредоносного CSS намного ниже, но возможность испортить сайт все еще существует, и кто знает, какие ошибки браузера также могут привести к тому, что CSS непреднамеренно откроет ваш сайт для хакера. Так что это тоже работа с использованием SRI.

Еще одна интересная вещь, которую вы можете сделать, это использовать Политика безопасности контента чтобы указать, что любой скрипт (или стили) на вашей странице должен используйте SRI, и, конечно, этот SRI должен подтвердить.

Content-Security-Policy: require-sri-for script;  

Это способ гарантировать, что SRI всегда используется, что может быть полезно на сайтах, над которыми работают несколько членов команды, которые могут или не могут быть полностью в курсе того, как делать что-то. Опять же, хорошим местом, чтобы узнать больше об этом, является всегда отличный Документы MDN для целостности подресурсов.

Последнее, о чем стоит поговорить, это поддержка SRI браузерами. Поддержка в современных браузерах широка, за исключением Internet Explorer. Тем не менее, благодаря обратно совместимому способу реализации спецификации ее можно безопасно использовать сразу. Браузеры, которые понимают integrity атрибут будет использовать хэш и проверять целостность, а старые браузеры будут продолжать работать как обычно. Конечно, вы не получите дополнительной защиты в этих старых браузерах, но вы получите ее в браузерах, которые предлагают поддержку.

Вывод

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

Использование уязвимости в системе безопасности часто сводится к тому, чтобы выровнять несколько мелких элементов. Если A существует, и вы можете сделать B возможным, то ошибка в C делает возможным D. Функции браузера, такие как SRI, дают нам хороший способ связать вещи еще немного и потенциально разорвать эту цепочку и помешать хакеру получить то, что он хочет. Более того, если вы можете интегрировать его в свой процесс сборки или CMS, вы сможете настроить его один раз, а затем забыть об этом, и это не будет доставлять вам повседневных неудобств.

Таким образом, я настоятельно рекомендую серьезно взглянуть на целостность субресурсов и внедрить ее на свои сайты, если сможете.

Сокрушительная редакция(ык, ил)



Источник

Статьи по Теме

Как использовать JSDelivr

Самый удобный для новичков способ добавить библиотеку в проект: Искать библиотеку Ищите исходный файл Скопируйте исходный файл Вставьте то, что вы скопировали, в проект. Это…

Ответы

Ваш адрес email не будет опубликован. Обязательные поля помечены *