В npm обнаружена новая волна червя Mini Shai-Hulud в пакете для TanStack Query

Атака на цепочку поставок NPM

В конце августа 2026 года в реестре npm появилась новая волна вредоносной кампании Mini Shai-Hulud. Злоумышленники опубликовали десять версий пакета @7nohe/openapi-react-query-codegen, предназначенного для генерации кода поверх библиотеки TanStack Query. Все версии вышли в течение примерно двадцати минут, причём пакет относится к категории с аудиторией более 150 тысяч загрузок в неделю. Такой широкий охват делает инцидент значимым для разработчиков, использующих экосистему JavaScript и TypeScript.

Описание

Механизм атаки построен на выполнении произвольных команд в момент установки. В восьми стабильных версиях запуск вредоносной нагрузки происходит через конфигурационный файл сборки, который обрабатывается утилитой node-gyp. Четыре версии, выпущенные чуть позже, дополнительно содержат предустановочный скрипт. В новых образцах команда скрыта последовательностью Unicode-символов, что затрудняет её поиск автоматическими средствами, проверяющими только стандартные поля пакета. Две первые опубликованные версии были предрелизными: одна из них содержала лишь подготовительный скрипт, скачивавший легитимную среду выполнения Bun и задававший переменные окружения для активации полной версии червя.

По данным JFrog Security Research, эта кампания продолжает серию атак, отслеживаемую с весны 2026 года. Ранее похожие варианты червя распространялись через другие npm-пакеты, в том числе в мае через пакеты, связанные с экосистемой AntV. В новой редакции изменились упаковка, текстовые строки и техника сокрытия, однако общая логика осталась прежней - кража учётных данных, перехват токенов доступа и повторная публикация скомпрометированных пакетов. Исследователи отмечают, что червь не является самостоятельным семейством, а представляет собой очередную вариацию уже известного вредоносного ПО.

Отдельного внимания заслуживает способ попадания пакета в реестр. В проекте использовался автоматизированный процесс выпуска, который реагировал на точное содержимое комментария к запросу на слияние: фраза npm publish запускала публикацию. Автор атаки оставил такой комментарий в чужом запросе, а система выпуска задействовала механизм доверенной публикации на основе открытого стандарта аутентификации OpenID Connect. В результате вредоносные версии получили легитимную подпись происхождения. Такая подпись подтверждает только то, что задание выполнялось в репозитории проекта, но не гарантирует чистоту опубликованного кода.

После установки червь ведёт себя так же, как более ранние представители семейства. Он собирает секреты из репозиториев GitHub, реестров npm, PyPI и RubyGems, а также из систем облачных провайдеров, хранилищ Vault и окружений Kubernetes. Вдобавок программа сканирует память процессов инфраструктуры непрерывной интеграции в поисках отметок о секретных значениях. Украденные данные сжимаются, шифруются и сохраняются в публичный репозиторий под учётной записью жертвы. Новая версия также передаёт похищенные токены PyPI на официальный сервер загрузки пакетов, чтобы отобрать из них рабочие и использовать для дальнейших атак.

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

Для закрепления в системе червь на Linux и macOS создаёт пользовательские службы автозапуска и фоновый монитор, который отслеживает состояние украденных токенов. Если владелец отзывает токен доступа, монитор получает соответствующий сигнал и может удалить содержимое домашней директории. Это превращает стандартную процедуру реагирования на инцидент в рискованную: без предварительной зачистки системы отзыв токенов способен уничтожить данные пользователя.

Временные рамки инцидента вызывают дополнительные вопросы. В конце августа в Австралии арестовали предполагаемых участников группы TeamPCP, связанной с предыдущими волнами Mini Shai-Hulud. Новый пакет появился в npm примерно через день после этих событий. Набор функций совпадает с прежними атаками, однако ключи шифрования и текстовые метки заменены. Точную причину такой последовательности установить невозможно. Речь может идти как об остаточном доступе прежней группы, так и о новом операторе, использующем те же инструменты.

Для защиты разработчикам рекомендуется проверить, не устанавливались ли затронутые версии пакета. Любая установка с выполнением жизненного цикла скриптов должна рассматриваться как компрометация системы. В число первоочередных мер входят изоляция заражённой машины, отключение созданных червём служб, удаление временных файлов и переход на безопасные версии пакета - 0.5.3, 1.6.2, 2.2.0 или 3.0.2. После очистки необходимо пересоздать файлы блокировки зависимостей и с чистого устройства сменить все учётные данные, включая токены GitHub, npm, PyPI, RubyGems, облачные и SSH-ключи.

Вредоносные версии уже детектируются средствами JFrog Xray и JFrog Curation. Инцидент показывает, что доверенная публикация не является гарантией безопасности, а старые сигнатуры прошлых кампаний не позволят выявить этот вариант червя. Защитникам следует ориентироваться на новые поведенческие признаки и особенно внимательно проверять npm-пакеты, которые запускают команды на этапе установки или обращаются к конфигурациям сборки нативных модулей. Только сочетание автоматического анализа и проверки источников позволяет снизить риск повторения подобных атак.

Индикаторы компрометации

Package

  • @7nohe/openapi-react-query-codegen

Domain

  • poopy.com

URL

  • https://api.github.com/search/commits
  • https://api.github.com/user/repos
  • https://fulcio.sigstore.dev/api/v2/signingCert
  • https://github.com/oven-sh/bun/releases/download/bun-v1.4.0/
  • https://raw.githubusercontent.com/oven-sh/bun/refs/heads/main/src/runtime/cli/install.sh
  • https://registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/
  • https://rekor.sigstore.dev/api/v1/log/entries
  • https://upload.pypi.org/legacy/

Комментарии: 0