Что, по данным Microsoft, произошло#
Microsoft сообщила, что обнаружила активную supply-chain атаку в экосистеме npm, связанную со скомпрометированными пакетами @antv. По данным Microsoft, злоумышленник получил доступ к аккаунту мейнтейнера и опубликовал вредоносные версии популярных пакетов для визуализации данных.
Семейство пакетов важно само по себе: библиотеки @antv часто используются в стеках для графиков и дашбордов. Microsoft пишет, что компрометация пошла дальше по цепочкам зависимостей и затронула downstream-библиотеки, включая одну с более чем 1 миллионом скачиваний в неделю. В этом и состоит ключевая проблема supply-chain атак: ущерб не всегда заканчивается на первом скомпрометированном пакете.
Вредоносная нагрузка запускалась во время npm install через хук preinstall. Microsoft описывает ее как обфусцированный JavaScript-файл размером около 499 КБ. Основной фокус был на CI/CD-средах, особенно GitHub Actions на Linux. В коде были проверки, из-за которых нагрузка в некоторых сценариях завершалась, если запуск происходил не в такой среде.
Microsoft также отмечает, что авторы аккаунта @antv позже подтвердили в тикете репозитория, что проблема решена. Но это не отменяет возможную экспозицию downstream-проектов. Публикация новых вредоносных версий могла быть остановлена, но у команд остается более сложный вопрос: устанавливал ли какой-либо build runner вредоносные версии, пока в окружении были секреты?
Почему это не просто неудачный релиз пакета#
Многие инциденты в npm ограничиваются выполнением кода при установке, кражей токенов или typosquatting. Здесь картина конкретнее. Анализ Microsoft описывает инструменты, нацеленные на кражу учетных данных CI/CD сразу на нескольких платформах.
По данным Microsoft, нагрузка искала секреты или токены, связанные с:
- GitHub и GitHub Actions
- Amazon Web Services
- HashiCorp Vault
- npm
- Kubernetes
- 1Password
Этот список хорошо описывает модель риска. Build runner часто получает временный доступ к коду, облачным API, package registries, deploy-ключам и хранилищам секретов. Если вредоносный код запускается там, ему может не понадобиться компрометировать ноутбук разработчика. Pipeline уже обладает нужным доверием.
Microsoft пишет, что нагрузка пыталась перечислять секреты репозиториев и организаций GitHub, искать personal access tokens и installation tokens, обращаться к AWS metadata services, читать AWS-файлы и переменные окружения, делать запросы к Secrets Manager, искать Vault tokens в нескольких локальных путях, читать Kubernetes service account tokens и взаимодействовать с CLI 1Password.
Особенно важен вектор GitHub Actions. По данным Microsoft, нагрузка находила процесс Runner.Worker на Linux, сканируя /proc, а затем пыталась извлекать секреты из памяти процесса. Это другой класс атаки, не просто вывод переменных окружения в лог. Secret masking защищает логи. Он не защищает автоматически процесс от чтения памяти кодом, который уже выполняется на том же runner с достаточными правами.
Microsoft также описывает попытку повышения привилегий через passwordless sudo rule с bind mount, а также манипуляцию DNS через /etc/hosts. Эти детали указывают, что злоумышленник пытался усилить локальный контроль над runner перед эксфильтрацией.
Как нагрузка скрывалась и передавала данные#
Microsoft описывает несколько уровней обфускации. Нагрузка заменяла легитимный index.js однострочным обфусцированным скриптом. Внутри использовался большой rotated array со строками в Base64 и декодированием во время выполнения. Критические строки, включая command-and-control домены и имена переменных окружения, были зашифрованы и расшифровывались только во время выполнения через кастомный механизм на базе PBKDF2 и SHA-256.
Само по себе это не делает вредоносный код уникальным. Но быструю проверку такое усложняет. Мейнтейнер или потребитель, открыв diff пакета, увидел бы плотный нечитаемый blob, а не нормальный прикладной код.
Важна и цепочка запуска. Microsoft описывает путь node → shell → bun → payload, причем Bun runtime устанавливался, если отсутствовал. Для защитников это еще один практический индикатор: неожиданная установка или запуск Bun внутри CI jobs, где он раньше не использовался.
Для эксфильтрации, по данным Microsoft, использовались два канала. Основной путь — HTTPS к зашифрованному command-and-control домену на порту 443, с предварительной DNS-проверкой и health probe. Резервный путь использовал Git Data API: создавались blobs, trees или commits в репозиториях жертв на незащищенных ветках.
Microsoft также сообщает, что malware создавал публичные репозитории в аккаунтах жертв с перевернутой строкой в описании: niagA oG eW ereH :duluH-iahS. На момент публикации Microsoft наблюдала более 2 200 таких репозиториев.
Этот артефакт может помочь найти экспозицию. Но его нельзя считать единственным сигналом. Если у нагрузки было несколько путей эксфильтрации, отсутствие публичного репозитория не доказывает, что runner был в безопасности.
Что проверить в первую очередь#
Практический вопрос не в том, импортирует ли проект @antv напрямую. Сначала нужно понять, подтянуло ли дерево зависимостей вредоносную версию в период экспозиции. Пост Microsoft стоит использовать как источник индикаторов пакетов и технических деталей, потому что точные затронутые версии и downstream-пути имеют значение.
Начните с данных о сборках и зависимостях:
- Проверьте lockfiles и логи package manager на наличие пакетов
@antvи затронутых downstream-зависимостей. - Посмотрите историю CI jobs и найдите установки, которые проходили в релевантное окно.
- Ищите неожиданный запуск
preinstall, связанный с путем пакета. - Проверьте логи runner и образы на неожиданную установку или выполнение Bun.
- Выделите сборки, которые запускались на GitHub Actions Linux runners и имели доступ к секретам.
Затем переходите к возможной утечке учетных данных, а не только к удалению пакета:
- Ротируйте GitHub tokens, npm tokens, облачные учетные данные и deploy keys, доступные затронутым jobs.
- Проверьте паттерны доступа к секретам GitHub repository, organization и Actions.
- Проверьте AWS CloudTrail и активность Secrets Manager на необычное перечисление или чтение.
- Изучите audit logs Vault на неожиданный token use, доступ к локальным токенам или listing секретов.
- Проверьте активность Kubernetes API от CI identities.
- Ищите неожиданные публичные репозитории, commits, blobs или branches, созданные automation accounts.
Если использовались self-hosted runners, считайте их зоной повышенного риска, пока они не проверены или не пересобраны. Ephemeral hosted runners снижают риск закрепления, но не устраняют риск кражи секретов во время job.
Чего не стоит утверждать без доказательств#
Исходные материалы не подтверждают любые возможные выводы. Microsoft описывает активную supply-chain атаку и подробные возможности нагрузки. Это не то же самое, что доказать кражу секретов у каждого downstream-пользователя.
Защитникам нужно разделять несколько вопросов:
- Была ли вредоносная версия в дереве зависимостей?
- Устанавливал ли ее CI job?
- Совпадало ли окружение с execution gates нагрузки?
- Были ли в тот момент доступны секреты?
- Удалась ли эксфильтрация через HTTPS или Git Data API?
Ответ «да» на первый вопрос не дает автоматически ответа на последний. Но если «да» получается на первые три, к ситуации нужно относиться серьезно: нагрузка была написана именно под такой сценарий.
Главный вывод о доверии в CI/CD#
Этот инцидент хорошо ложится в уже знакомый паттерн. Экосистемы пакетов — не просто удобный слой для разработчиков. Это путь выполнения кода внутри build systems. Установка пакета может превратиться в запуск кода там, где организации концентрируют учетные данные.
Поэтому политика зависимостей в CI/CD — это security boundary. Lockfiles, provenance, token scoping, минимизация секретов и ephemeral runners не бюрократия. Они определяют, какой ущерб сможет нанести один скомпрометированный аккаунт мейнтейнера.
Самый короткий вывод: не оценивайте npm supply-chain инциденты только по влиянию на runtime приложения. Проверяйте build path. Именно там находились секреты.