Mini Shai-Hulud ударил по npm и доверию в CI

Новая supply-chain-кампания затронула сотни пакетов, GitHub Actions и CI-секреты. Что проверить командам прямо сейчас.

2026-05-24 GIGATAP Team #security
#supply-chain-security#npm#ci-cd

Что произошло#

Новая supply-chain-кампания Mini Shai-Hulud затронула сотни open-source-пакетов. Об этом пишет SecurityWeek со ссылкой на данные Microsoft, Socket, Wiz и StepSecurity.

Первый известный взлом связан с аккаунтом npm-мейнтейнера atool. У него был доступ к нескольким пакетам в пространстве имён @antv; кроме того, он публикует timeago.js — пакет, у которого, по данным SecurityWeek, около 1,5 млн загрузок в неделю.

После компрометации аккаунта атакующие выпустили вредоносные версии пакетов. Затем атака пошла ниже по цепочке зависимостей и затронула другие популярные пакеты, включая echarts-for-react, для которого источник указывает примерно 1,1 млн загрузок в неделю.

Масштаб оказался шире одного namespace. Microsoft наблюдала около 639 вредоносных версий среди затронутых пакетов из экосистем визуализации данных, графов, карт, диаграмм и React-компонентов. Socket сообщил, что отслеживает 1 055 версий в 502 уникальных пакетах в более широкой кампании. Подсчёт Socket охватывает npm, PyPI и Composer, при этом почти вся активность пришлась на npm: 1 048 npm-версий в 498 уникальных npm-пакетах, плюс шесть записей PyPI в трёх пакетах и одна запись package-version в Composer.

По данным источника, кампания также затронула GitHub Actions и расширение VS Code. Wiz связал компрометацию популярного GitHub Action actions-cool/issues-helper с той же активностью. StepSecurity сообщил, что пострадал и Microsoft Durabletask Python SDK: три вредоносные версии были загружены в PyPI за 35 минут.

Эти детали важны: речь не только о проблеме реестра пакетов. Payload был нацелен на машины разработчиков, build-системы и CI/CD-среды, где секреты часто находятся в памяти, конфигурационных файлах или переменных окружения.

Что делал payload#

Большинство затронутых пакетов, по сообщениям исследователей, находились в namespace @antv и содержали install-time payload. Это значит, что вредоносный код мог запускаться при установке пакета — ещё до того, как приложение явно импортировало или использовало его.

SecurityWeek цитирует исследователей, которые описывают многоступенчатую цепочку заражения. Первичные payload загружали дополнительный код с инфраструктуры, размещённой на GitHub. Вторичные payload были рассчитаны на кражу учётных данных и закрепление в системе.

Socket описал payload как обфусцированный и способный читать память процесса GitHub Actions runner, чтобы извлекать замаскированные CI/CD-секреты в открытом виде. Это ключевой момент. CI-системы часто маскируют секреты в логах, но маскирование вывода не защищает секрет от вредоносного процесса, который выполняется на том же runner.

По сообщениям, тот же payload собирал учётные данные из более чем 130 путей к файлам. Среди целей были cloud-ключи и developer-секреты, связанные с AWS, GCP, Azure, Kubernetes, HashiCorp Vault, криптокошельками и инструментами разработки.

Украденные данные уходили по двум каналам. Как и в ранней активности Mini Shai-Hulud, исследователи наблюдали exfiltration через GitHub-репозитории и через резервный сервер. По данным источника, StepSecurity также обнаружил более 2 200 GitHub-репозиториев с украденными данными.

Socket также сообщил, что внутри malware была логика злоупотребления npm-реестром. Код мог проверять npm-токены через registry API, перечислять пакеты, доступные владельцу токена для сопровождения, скачивать package tarballs, внедрять вредоносный payload, добавлять hook preinstall, повышать версии пакетов и заново публиковать изменённые пакеты от имени скомпрометированного мейнтейнера.

Такое поведение объясняет, почему подобные кампании распространяются быстро. После компрометации токена или аккаунта мейнтейнера атакующий использует сам реестр как механизм доставки. Следующей волне не нужно обманывать каждый проект отдельно: она проходит по уже существующим связям доверия.

Что изменилось в этой волне#

Источник описывает это как новую supply-chain-атаку Mini Shai-Hulud с признаками сходства с прежними кампаниями. Схема exfiltration через GitHub-репозитории и резервный сервер похожа на раннюю активность.

Но исследователи также отмечают изменения.

Wiz сообщил, что malware загружал и выполнял Python-код с инфраструктуры, контролируемой атакующими. Это даёт операторам возможность дальнейшего remote execution на скомпрометированных системах, а не только разовой кражи во время установки.

StepSecurity также наблюдал persistent backdoors, которые попадали в Claude Code. Источник не даёт достаточно деталей, чтобы описать точный механизм persistence или полный охват этих backdoors. Безопасный вывод уже: исследователи видели поведение, которое выходило за рамки простой кражи учётных данных и было ближе к долгосрочному доступу на выбранных системах.

Из-за этого растёт операционный риск. Если затронутый CI runner или машина разработчика установили одну из вредоносных версий пакетов, простой ротации npm-токенов может быть недостаточно. Хост, на котором выполнился second-stage payload, может потребовать более глубокой проверки, пересборки или замены — в зависимости от среды и уровня воздействия.

Почему это важно для разработчиков и security-команд#

Главный урок не в том, что npm небезопасен. Проблема в другом: современные build-цепочки концентрируют доверие в небольшом числе аккаунтов, токенов, install scripts и автоматизированных путей.

Популярный frontend-пакет может находиться внутри тысяч приложений. Токен мейнтейнера может публиковать множество пакетов. GitHub Actions runner может держать cloud-ключи, deployment-токены, npm-токены, Kubernetes-конфиги и секреты репозитория. Один вредоносный путь через preinstall быстро пересекает эти границы.

Кампания также напоминает: число загрузок не говорит о безопасности. Пакеты с миллионами weekly downloads всё равно могут стать каналом атаки, если аккаунт мейнтейнера или publishing credential скомпрометированы. Популярность может даже увеличить охват, потому что такой пакет уже разрешён политиками зависимостей и закеширован в build-системах.

Атака также бьёт по распространённому представлению о CI-секретах. Многие команды считают masking сильной защитой. На практике это в основном гигиена логов. Если вредоносный код выполняется в том же job или runner context, он может получить доступ к секретам до того, как они вообще попадут в лог.

Что проверить сейчас#

Командам, которые используют npm, PyPI, Composer, GitHub Actions или расширения VS Code в build-процессах, не стоит воспринимать инцидент как простую уборку в npm.

Практические проверки:

  • Проверьте, входили ли в ваше дерево зависимостей затронутые пакеты @antv, timeago.js, echarts-for-react, версии Microsoft Durabletask Python SDK, указанные исследователями, или GitHub Action actions-cool/issues-helper в релевантный период.
  • Просмотрите package lockfiles, build-логи, записи dependency cache и provenance артефактов на предмет неожиданных версий, опубликованных во время кампании.
  • Ищите выполнение install-time scripts, особенно hook preinstall, добавленный в неожиданных версиях пакетов.
  • Ротируйте npm, PyPI, GitHub, cloud, Kubernetes, Vault и deployment-учётные данные, которые могли быть доступны затронутым машинам разработчиков или CI runners.
  • Считайте self-hosted CI runners потенциально заражёнными, если они устанавливали затронутые версии. Где возможно, пересоберите runners с чистого состояния.
  • Проверьте GitHub-организации на неизвестные репозитории, подозрительные коммиты и репозитории с выгруженными секретами.
  • Пересмотрите npm-токены: scope, возраст, использование в автоматизации и права на пакеты. Удалите токены, которые шире, чем нужно.
  • По возможности закрепляйте GitHub Actions на полные commit SHA, особенно для third-party actions в чувствительных workflows.

Точный ответ зависит от воздействия. Проект, который подтянул скомпрометированный пакет только в локальной песочнице, имеет другой профиль риска, чем production deployment pipeline, где во время установки были доступны cloud-ключи и registry-токены.

Чего не стоит утверждать#

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

Они также не показывают единый уровень воздействия для npm, PyPI, Composer, GitHub Actions и VS Code. Кампания, судя по данным, была координирована сразу по нескольким поверхностям, но механика и exposure различаются по экосистемам.

С attribution тоже нужно быть аккуратнее. Источник упоминает сходство с прежними атаками Mini Shai-Hulud и контекст известной группы, но для защитников практическая проблема немедленная: вредоносные версии пакетов, кража учётных данных, злоупотребление реестром и возможная persistence.

Итог#

Эта кампания показывает, почему защита supply chain не может останавливаться на dependency scanning.

Слабое место — весь путь целиком: аккаунт мейнтейнера, реестр пакетов, install script, CI runner, секреты, publishing token и downstream-права на пакеты. Mini Shai-Hulud использовал этот путь как систему.

Защита должна действовать так же системно. Проверьте exposure по зависимостям. Ротируйте доступные секреты. Пересоберите затронутые runners. Сужайте scope токенов. Относитесь к install scripts и third-party actions как к выполнению кода — потому что это именно оно.