Исследователь Алекс Бирсан обнаружил простой способ взлома внутренних систем. Чтобы выполнить код на сервере, достаточно подменить частные пакеты с зависимостями одноимёнными пакетами из общедоступных репозиториев. Стандартные менеджеры пакетов NPM, PyPI, RubyGems фактически делали это сами. При этом администраторы не получали никаких уведомлений, а системы продолжали работать без сбоев.
Метод основан на том, что компании используют в приложениях зависимости из стандартных репозиториев, а также внутренние зависимости, которые хранятся в собственных репозиториях и не распространяются публично. Если знать имена пакетов с внутренними зависимостями и создать пакеты с такими же именами в публичных репозиториях, то можно выполнить код на серверах компании. Это связано с тем, что пакетные менеджеры вроде npm, pip и gem пытаются загрузить внутренние зависимости компаний в том числе из публичных репозиториев. Проблема не специфична для NPM, PyPI, RubyGems и проявляется в других системах, среди которых NuGet, Maven и Yarn.
Идея такой атаки появилась после того, как исследователь изучил файлы манифеста package.json из пакета npm, который использовался внутри системы PayPal. Бирсан обнаружил, что некоторых пакетов нет в общедоступном репозитории npm. Это были внутренние пакеты, созданные PayPal. После этого исследователь начал поиск имён внутренних пакетов в репозиториях GitHub или в CDN известных компаний. Собрав базу, он создал поддельные пакеты с такими же именами в публичных репозиториях, таких как npm, PyPI и RubyGems. Каждый пакет выходил под реальной учётной записью и содержал пояснение, что он предназначен для исследования безопасности.
Вскоре стало понятно, что если пакет с одним и тем же именем присутствует и в общедоступном, и в частном репозитории, то публичный пакет получает приоритет. Используя эту технику, Бирсан провёл успешные атаки на серверы Microsoft, Apple, PayPal, Shopify, Netflix, Tesla, Yelp и Uber. В PyPI на приоритет загрузки влиял номер версии — загружалась наиболее свежая версия пакета, вне зависимости от репозитория. В NPM и RubyGems приоритет зависел только от репозитория.
Митап «Жажда скорости: DevSecOps за 2 недели»
16 февраля в 16:00, Онлайн, Беcплатно
tproger.ru
События и курсы на tproger.ru
75 % всех зафиксированных запусков кода были связаны с загрузкой NPM-пакетов. Это объясняется тем, что имён внутренних модулей JavaScript было найдено намного больше, чем имён зависимостей на Python и Ruby. Внутренние gem-пакеты были обнаружены у 8 компаний, 4 из них удалось атаковать, создав дубликат пакета в RubyGems. Среди жертв оказалась Spotify, сборочный сервер которой установил поддельный пакет shopify-cloud спустя всего несколько часов после его публикации. Поддельный Node.js-пакет idms-pmrpc попал в сеть Apple, в том числе на сервер, связанный с Apple ID.
О своих выводах исследователь сообщал компаниям. Он подчеркивает, что каждая организация, которая была подвергнута атаке, предоставила разрешение на проверку своей безопасности либо в публичной программе вознаграждения, либо в частной форме. Компании уже выплатили ему вознаграждение — всего Бирсан получил 130 тысяч долларов.
Как защититься от атак на зависимости?
После изучения проблемы компания Microsoft опубликовала рекомендации по защите сборочных систем от атак на зависимости:
-
В PyPI рекомендуется использовать опцию «–index-url» вместо «–extra-index-url» для переопределения приоритета обработки зависимостей.
В NuGet в nuget.config в секции packageSources рекомендуется использовать запись <clear /> для удаления наследуемых конфигураций, а также явно добавлять внутренние репозитории через <add />.
В Maven рекомендуется настроить одно общее зеркало при помощи опций <mirrorOf>*</mirrorOf> и перенаправлять в него все запросы к репозиториям. Другой вариант — переопределение репозиториев по умолчанию при помощи настройки <releases>.
В NPM и Yarn в пакетах рекомендуется определить scopeprefix для привязки репозитория к каждому пакету (возможна привязка только одного репозитория).
Источник: