Возможна атака на цепочку поставок через атаку MavenGate
![]() |
Критичность: ВЫСОКИЙ |
Модуль: Анализ компонент с открытым исходным кодом |
Описание
Приложение использует библиотеку с открытым исходным кодом, которая может участвовать в атаке на цепочку поставок (под названием MavenGate).
В чем заключается суть атаки MavenGate, почему она стала возможной и почему она так опасна? Обратимся к первоисточнику и посмотрим, из чего состоит типичный Gradle-проект и как работает механизм управления зависимостями.
-
Каждый Gradle-проект содержит список репозиториев, откуда необходимо выгружать зависимости. Они могут быть разными, но наиболее популярные проекты — MavenCentral, JCentral и JitPack с Google (для Android). Репозитории делятся на приватные, где публиковать компоненты могут только их правообладатели (например, Google-репозиторий), и публичные — где каждый может размещать что угодно (среди них как раз MavenCentral, JCenter и т. д.).
Указание перечня репозиториев в файле сборки gradle -
Список зависимостей имеет формат
groupId:artifactId:version
, например,com.google.code.gson:gson:2.10.1
.Описание зависимостей в файле сборки
Сборщик идет по репозиториям сверху вниз и скачивает указанную версию из первого репозитория, в котором она найдена. Основным моментом здесь является тот факт, что большинство разработчиков библиотек публикует их только в одном (максимум в двух) репозиториях, а во всех остальных нет.
Но как опубликовать свою библиотеку, что для этого нужно? Как правило, процесс очень похож во многих репозиториях. Чтобы выложить библиотеку, необходимо владеть доменом, который относится к ее group.id
. То есть, чтобы выложить пакет с именем ru.stingraymobile
, необходимо быть владельцем домена stingraymobile.ru
. И чтобы это подтвердить, на момент регистрации необходимо добавить TXT-запись с определенным значением в ваш домен.
Злоумышленник определяет библиотеки, для которых доступна регистрация домена, покупает его и после этого загружает библиотеку с полезной нагрузкой во все репозитории, где ее нет. Именно на этой особенности и построена рассматриваемая атака: библиотеки, домены которых доступны для свободной регистрации, уязвимы и могут быть подменены злоумышленниками в процессе сборки приложения.
Пример эксплуатации
Чтобы понять, как можно реализовать эту атаку, разберем пример. Возьмем библиотеку org.xmlmatchers
. По данным Maven, она используется в 62-х проектах и опубликована только на MavenCentral. Домен xmlmatchers.org
свободен для регистрации и стоит $9.99 в год.
Вот какой может быть последовательность действий злоумышленника:
-
Покупает домен
xmlmatchers.org
за 10 долларов. -
Регистрируется во всех публичных репозиториях, где первичная валидация происходит по домену.
-
Загружает в эти репозитории библиотеку, которая содержит полезную нагрузку в дополнение к основному функционалу с той же версией, что и в MavenCentral. Дополнительно загружает на одну минорную версию выше.
В результате:
-
Все пользователи, применяющие библиотеку напрямую (и у кого первым установлен не MavenCentral-репозиторий), получат версию злоумышленника.
-
Все пользователи, которые подключают ее напрямую, получат сообщение от IDE, что библиотеку можно обновить.
-
Все проекты, использующие эту зависимость (и у кого первым установлен не MavenCentral-репозиторий), получат версию злоумышленника.
Повторяем это действие для всех найденных библиотек со свободными доменами.
Есть и второй вектор атаки — для его реализации нужно просканировать все репозитории, кроме Central, на библиотеки со свободными доменами. По полученному списку проверить, каких из них нет в основном Maven-репозитории.
Далее путь очень похожий:
-
Покупается домен.
-
Дорабатывается и заливается библиотека в MavenCentral.
-
Все проекты и пользователи, у которых первым в списке стоит Central-репозиторий, получают библиотеку с полезной нагрузкой
Весьма несложный путь для атак на достаточно большое количество проектов.
Рекомендации
Есть несколько вариантов, как защититься от этого типа атаки (лучше делать все это вместе):
Первый способ: собрать SBOM-файл для своих Java- и Android-приложений и посмотреть, что именно они используют — все прямые и транзитивные зависимости. Провести анализ и выявить библиотеки, домены которых свободны для продажи или куплены за прошедшие несколько недель, и исключить эти зависимости из проекта, если это возможно. Дополнительно обязательно проверить, нет ли в ваших файлах сборки пакетов с версией, которая ссылается на самую свежую без прямого указания. В случае обнаружения подобных зависимостей необходимо явно зафиксировать версию библиотеки.
Второй способ: проверить контрольную сумму пакета (целостность) или хэш от загруженной библиотеки. И проверять загружаемые библиотеки при сборке на соответствие этим хэш-суммам.
Третий способ: проверка подписи загружаемых библиотек, но, как показывает практика, мало кто из разработчиков публикует открытые ключи. Тем не менее это один из самых эффективных способов защиты от данной атаки.
Стоит сказать и о разработке в закрытом контуре. Компании, которые используют внутренние репозитории в режиме зеркалирования (библиотека, перед тем как попасть к разработчику или в систему сборки, сначала загружается во внутренний репозиторий и при последующих обращениях к ней отдаёт сохраненный ранее файл), менее подвержены этому типу атаки, чем те, кто загружает библиотеки из публичных репозиториев напрямую. Тем не менее, рекомендуется проверить все библиотеки, которые содержатся в проксирующих репозиториях, на предмет возможности захвата домена, посмотреть, какие источники для загрузки Java-библиотек разрешены и какие версии были загружены с начала года. И более детально изучить их, выяснить, а те ли они, за кого себя выдают, или кто-то уже успел загрузить «правильную» версию.