Node-gyp worm ломает доверие npm через установку пакетов

Supply chain worm через node-gyp использует binding.gyp для скрытого выполнения кода на этапе установки, обходя lifecycle-хуки и CI-защиту.

2026-06-13 GIGATAP Team #security
#software supply chain#node-gyp#npm security

Что изменилось в атаке на npm supply chain#

Координированный supply chain worm, распространяющийся через entity[“company”,“npm”,“JavaScript package registry”], смещает выполнение кода из классических lifecycle-хуков в механизм нативной сборки. Вместо preinstall или postinstall используется внедрение логики в binding.gyp, который интерпретируется во время компиляции.

Система сборки entity[“software”,“node-gyp”,“Node.js native addon build tool”] обычно воспринимается как детерминированный слой компиляции для нативных модулей Node.js. Атакующие эксплуатируют это доверие: при обнаружении нативного модуля npm автоматически запускает node-gyp, создавая скрытую поверхность выполнения, которую большинство инструментов безопасности не классифицируют как script event.

Кампания, связанная с семействами Phantom Gyp и Miasma и паттернами worm-подобного распространения, охватывает десятки пакетов и сотни версий. После запуска полезная нагрузка извлекает учетные данные из окружений разработчиков и CI, включая токены entity[“company”,“GitHub”,“code hosting platform”], entity[“company”,“AWS”,“cloud computing platform”], entity[“company”,“Google Cloud”,“Google Cloud platform”], entity[“company”,“Microsoft Azure”,“Microsoft cloud platform”], а также секреты из менеджеров вроде entity[“software”,“HashiCorp Vault”,“secrets management tool”]. Скомпрометированные данные используются для закрепления доступа и дальнейшего распространения через CI и процессы публикации пакетов.

Очистка dist-tag не гарантирует устранение риска: вредоносные версии остаются доступными через прямое указание версии в lockfile. Это сохраняет экспозицию даже после частичного реагирования на уровне registry.

Определение: worm цепочки поставок ПО#

Worm цепочки поставок ПО — это вредоносное ПО, которое распространяется через доверенные dependency-экосистемы, компрометируя разработчиков или build-процессы и автоматически реплицируясь между пакетами без прямого взаимодействия пользователя.

Как работает install-time выполнение через node-gyp#

Атака опирается на стандартное поведение npm при установке нативных модулей. Если пакет содержит binding.gyp, система предполагает необходимость компиляции и автоматически вызывает node-gyp.

В нормальных условиях это компилирует C/C++ addon для Node.js. В скомпрометированных пакетах конфигурация сборки модифицируется так, чтобы внедрять выполнение команд через допустимые директивы build-layer и особенности интерпретации конфигурации.

Выполнение происходит на этапе configure-фазы сборки, до компиляции. Это критично: большинство систем мониторинга ориентированы на lifecycle-скрипты, а не на поведение build system. Логи часто выглядят как обычная компиляция, маскируя факт выполнения кода.

Фактически меняется модель доверия: вместо package.json как единственной точки исполнения, атакующий использует конфигурацию сборки как исполняемый примитив.

Почему это обходит модели безопасности#

Большинство npm security-инструментов предполагает, что выполнение при установке происходит через scripts. Поэтому контроль строится вокруг preinstall, install и postinstall.

Node-gyp ломает эту модель, перенося выполнение в слой build inference.

Параметр Lifecycle scripts node-gyp build execution
Триггер preinstall / postinstall обнаружение нативной сборки
Видимость высокая (явные скрипты) низкая (скрытый build-этап)
Мониторинг зрелые инструменты ограниченное покрытие
Поверхность атаки package.json scripts binding.gyp конфигурация
Детектируемость сильные эвристики слабые эвристики

Возникает разрыв между доверием к пакету и доверием к build-системе. Контроли, рассчитанные на script execution, не покрывают конфигурационно-управляемые сборки, хотя обе модели могут выполнять произвольный код при компрометации.

Что проверить#

  • проверьте lockfiles на зафиксированные версии, связанные с затронутыми диапазонами пакетов
  • обновите и пересоберите CI pipelines с учетом возможного запуска node-gyp
  • проведите аудит build-логов на неожиданные действия в configure-фазе
  • ротируйте учетные данные разработчиков, CI и облачных провайдеров при любой вероятной экспозиции
  • мониторьте токены и ключи в системах CI/CD после установки зависимостей

Операционное сдерживание и реагирование#

Предполагается, что выполнение могло произойти уже на этапе установки, даже без явных аномалий в lifecycle-скриптах.

CI-раннеры следует изолировать, токены CI систем отозвать, сессии разработчиков инвалидировать. Повторная установка зависимостей рассматривается как потенциальный повторный запуск вредоносного build-кода, если среда не очищена.

Обычное обновление пакетов не устраняет риск, если lockfile продолжает фиксировать скомпрометированные версии. Требуется полное пересоздание dependency tree, а не инкрементальные апдейты.

Что не стоит переоценивать#

Атрибуция исходной компрометации ограничена наблюдаемым поведением registry и анализом пакетов. Первичный вектор взлома аккаунтов maintainer’ов остается не полностью установленным.

Также некорректно считать node-gyp источником уязвимости. entity[“software”,“node-gyp”,“Node.js native addon build tool”] — легитимный инструмент сборки в экосистеме Node.js. Риск возникает из-за компрометации пакетов, использующих стандартный build-path, а не из-за самого инструмента.

FAQ#

Чем это отличается от обычного npm malware?
Обычные атаки используют lifecycle-скрипты в package.json. Здесь выполнение происходит через native build system, который часто не попадает в мониторинг script execution.

Почему lockfile не защищает?
Lockfile фиксирует детерминированные версии. Если вредоносная версия уже зафиксирована, она продолжит устанавливаться даже после удаления из registry.

Можно ли отключить node-gyp?
Глобальное отключение ломает легитимные нативные зависимости. Защита должна быть на уровне доверия к зависимостям и проверки происхождения, а не отключения build-инфраструктуры.