Что изменилось в атаке на 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-инфраструктуры.