Как я могу убедиться, что мои файлы JavaScript, доставленные через CDN, не изменены?

88

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

Я понимаю, что задача очень проста, если я использую SSL, но все же я хочу убедиться, что нужные файлы обслуживаются даже по HTTP без SSL.

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

Есть ли встроенный в браузеры метод проверки автора файлов JavaScript? Могу ли я что-нибудь сделать, чтобы сделать это безопасным способом?

баба26
источник
13
Хотя мне этот вопрос интересен, разве он не не по теме?
evolutionxbox
20
зачем вам обслуживать файлы по http?
njzk2 01
12
«Но почему нет такого механизма?» Потому что это действительно сложно . Как только ваши данные покинули ваш сервер, это тост. HTTPS помогает, но если это обычное HTTP-соединение, любая проверка может завершиться неудачно (или, скорее, пройти). Атака MITM может просто изменить вашу ожидаемую сигнатуру и / или сигнатуру того, что вам предоставляется, до того, как браузер оправдает ожидания. Итак, когда пользователь получает некоторую полезную нагрузку, это будет считаться полностью безопасным ... хотя это не обязательно.
ВЛАЗ 01
4
«Но почему нет такого механизма?» Потому что на HTTPS уже есть дешевое, эффективное и широко применимое решение.
Кевин Крамвиде 01
9
Вероятно, это должно быть на ServerFault или Security, поскольку на самом деле речь идет о безопасном обслуживании файлов, и любое отношение к программированию является лишь косвенным, поскольку указанные файлы представляют исходный код.
underscore_d

Ответы:

140

Фактически, такая функция в настоящее время разрабатывается под названием Subresource Integrity . Посмотрите на integrityатрибут <script>тега. Хотя он еще не полностью принят повсеместно , он выполняет именно эту цель.

integrity

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

Источник

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

Источник


Пример:

<script src="https://example.com/example-framework.js"
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
    crossorigin="anonymous"></script>

Однако обратите внимание, что это не защитит вас от атак «Человек посередине», если вы передаете свои ресурсы через простой HTTP. В этом случае хэш-код может быть подделан злоумышленником, что сделает защиту от манипулируемых файлов сценариев бесполезной.

По этой причине вы всегда должны использовать безопасные HTTPS-соединения вместо обычного HTTP в дополнение к мерам безопасности, описанным выше.

Тимо
источник
9
Я думаю, стоит упомянуть, что проверку целостности можно легко подделать, если предположить, что OP планирует отправлять свой HTML-код в HTTP, а также свои файлы ресурсов. Если их сайт - HTTPS, и они хотят обслуживать ресурсы через HTTP, то большинству браузеров это не понравится, и они будут молча игнорировать ресурсы HTTP.
MonkeyZeus 01
3
@MonkeyZeus Это будет правдой только в случае атаки MITM или если наш собственный сервер скомпрометирован, верно? Насколько я понимаю, вопрос явно задает вопрос, как защититься от взломанного CDN.
Timo
10
@TimoSta Совершенно верно! Без этих проверок, если вы включите скрипт, например, от https://code.jquery.com/, то любой, кто взломает, code.jquery.comсможет XSS вашего сайта, независимо от того, осуществляется ли code.jquery.comдоступ через HTTPS. При наличии этих проверок злоумышленник может только предотвратить загрузку скриптов, но не заменить их вредоносными.
Ajedi32 01
1
@MonkeyZeus Я добавил примечание к своему ответу, выразив вашу озабоченность. Вы согласны с формулировкой?
Timo
1
@TimoSta Очень мило, мне нравится! кстати, я сделал +1 еще до того, как опубликовал свой первый комментарий :-)
MonkeyZeus 01
36

Вы ищете проверки целостности подресурсов .

Например, вот фрагмент jQuery CDN:

<script src="https://code.jquery.com/jquery-3.1.0.js"
        integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="
        crossorigin="anonymous"></script>
Брайан
источник
2
Совершенно бесполезно, потому что злоумышленник может изменить поле целостности одновременно с изменением загружаемого вами сценария.
Гонки легкости на орбите
15
@LightnessRacesinOrbit: Нет, если вы контролируете свой собственный домен, доступ к которому осуществляется через HTTPS, но не контролируете code.jquery.com. Это может защитить вас от взлома code.jquery.com.
SilverlightFox
2
@SilverlightFox: Ладно, совершенно бесполезно против атак MITM *
Гонки
@LightnessRacesinOrbit Да. Все еще очень полезно и предотвратило бы эту атаку, например: bleepingcomputer.com/news/security/…
Адриан Муат,
6

Отказ от ответственности: как всегда, вы должны рассматривать эти механизмы только как полезные при использовании https, поскольку их можно легко отключить через MitM с помощью http.

В дополнение к механизму, описанному в приведенных выше ответах, вы также можете использовать заголовки HTTP-ответа политики безопасности содержимого на родительской странице.

http://www.html5rocks.com/en/tutorials/security/content-security-policy/

Политика безопасности содержимого: script-src 'sha256-qznLcsROx4GACP2dm0UCKCzCG-HiZ1guq6ZZDob_Tng ='

Здесь следует отметить несколько моментов. Префикс sha * - указывает алгоритм, используемый для генерации хэша. В приведенном выше примере используется sha256-. CSP также поддерживает sha384- и sha512-. При генерации хеша не включайте теги. Также имеют значение использование заглавных букв и пробелов, включая начальные и конечные пробелы.

Используя Chrome 40 или новее, вы можете открыть DevTools и перезагрузить страницу. Вкладка «Консоль» будет содержать сообщения об ошибках с правильным хешем sha256 для каждого из ваших встроенных скриптов.

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

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

Фабио Бельтрамини
источник
существует уже довольно давно, но поддержка браузеров не очень хорошая. caniuse.com/subresource-integrity
Sp0T 02
@ Sp0t - Целостность подресурсов (о чем ваша ссылка) - это механизм в других ответах. Мой ответ касается политики безопасности контента, которая имеет гораздо лучшую поддержку,
Фабио Бельтрамини,
3

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

ddyer
источник
2

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

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

/ etc / hosts:

#  ...
1.2.3.4    vile-pirates.org    trustworthy.cdn
#  ...
Эрик Тауэрс
источник
2
Первое предложение явно неверно. Что делать, если ссылающаяся страница загружается через HTTPS, а файл JavaScript загружается через HTTP-not-S?
user253751 02 авг.2016,
Или что, если скомпрометирован сам CDN, а не ваш собственный сервер?
Ajedi32 02
@immibis: Я предпочитаю предположить, что OP не настолько иррационален, чтобы предлагать такой сценарий.
Эрик Тауэрс
1
@immibis Разве не поэтому браузеры обычно не разрешают страницам HTTPS загружать JS через HTTP?
Barmar 02
1
@immibis Я говорил, что это улучшает ситуацию, что даже невозможно, потому что браузеры это запрещают.
Barmar 02
1

Вы можете гарантировать это с помощью целостности субресурсов. Многие общедоступные CDN включают хэши SRI во встраиваемый код, предлагаемый на веб-сайтах CDN. Например, на PageCDN, когда вы нажимаете файл jquery на странице jQuery CDN , вы получаете возможность либо скопировать URL-адрес, либо использовать тег скрипта, содержащий хэш SRI, как показано ниже:

<script src="https://pagecdn.io/lib/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>

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

На данный момент эта функция поддерживается 91% браузеров по всему миру. Подробнее о caniuse .

5377037
источник