Червь Shai-Hulud добрался до npm: 444 пакета заражены, 2 млрд скачиваний в месяц
Новая версия червя Shai-Hulud заразила 444 пакета npm, которые суммарно скачивают около двух миллиардов раз в месяц. Среди пострадавших оказались широко используемые зависимости keyv, flat-cache и cache-manager. ChainDrop распространяется необычным способом: вредоносный код может попасть в опубликованный пакет, хотя исходный репозиторий на GitHub останется чистым. Дополнительный путь заражения проходит через конфигурационные файлы VS Code и Claude Code, поэтому в некоторых случаях разработчику достаточно открыть подготовленную злоумышленниками ветку проекта.
Shai-Hulud обнаружили в сентябре 2025 года. Название червь получил в честь гигантских песчаных существ из «Дюны» Фрэнка Герберта. Новую разновидность, обнаруженную в августе 2026 года, назвали ChainDrop. Механизм заражения заметно изменился: вместо внедрения вредоносного кода только через обычные изменения в репозитории червь использует опубликованные архивы npm, украденные токены и настройки инструментов разработки.
Масштабную кампанию заметили 4 августа. К тому моменту заражение затронуло 444 пакета от нескольких издателей. Среди них были компоненты, которые разработчики часто подключают не напрямую, а получают вместе с другими зависимостями. Поэтому заражённая библиотека способна оказаться глубоко внутри дерева пакетов, хотя автор приложения никогда её специально не устанавливал и даже не знает о её присутствии.
Обычная установка через npm install остаётся одним из способов запустить вредоносный код, но ChainDrop этим не ограничивается. Червь добавляет команды автоматического запуска в файлы конфигурации репозитория. В частности, атакующие используют .claude/settings.json и .vscode/tasks.json. Подобные файлы управляют поведением Claude Code и задачами Visual Studio Code. Если внутрь добавить команду запуска вредоносного скрипта, открытие подготовленной ветки проекта может запустить следующий этап атаки без отдельного запуска заражённой программы вручную.
Проверка исходного кода тоже не всегда обнаружит вмешательство. ChainDrop умеет распространяться через tarball-архивы, которые npm использует для доставки опубликованных пакетов. Содержимое такого архива может отличаться от файлов в связанном Git-репозитории. Поэтому злоумышленнику необязательно оставлять вредоносный коммит в истории проекта.
После запуска ChainDrop ищет в системе токены npm с полными правами записи. Одновременно червь собирает другие секреты, включая облачные ключи и учётные данные. Поиск охватывает конфигурационные файлы командной оболочки, переменные окружения и данные в оперативной памяти работающих процессов. Найденную информацию вредонос шифрует и отправляет на серверы атакующих.
Особенно опасны npm-токены, позволяющие публиковать новые версии пакетов. Получив такой токен, ChainDrop определяет все пакеты, к которым у владельца есть полный доступ, и загружает их tarball-архивы напрямую из npm. Git-репозиторий на этом этапе не используется.
Затем червь добавляет собственную нагрузку в архив и заново собирает пакет. После публикации заражённая версия появляется в npm, хотя история исходного проекта может не содержать подозрительных изменений. Разработчик способен открыть GitHub, внимательно проверить последние коммиты и не найти там вредоносного кода, потому что заражение произошло уже на уровне опубликованного пакета.
Параллельно ChainDrop ищет учётные данные GitHub. Если подходящий токен найден, вредонос обращается к GitHub API, получает список доступных репозиториев и веток и записывает туда вредоносную конфигурацию для инструментов разработки.
Заражённые .claude/settings.json и .vscode/tasks.json превращают репозиторий в ещё один канал распространения. Когда другой разработчик открывает подготовленную ветку в Claude Code или Visual Studio Code, фоновая задача может запустить сбор секретов на новом компьютере. Украденный npm-токен затем даёт доступ к очередным пакетам, а данные GitHub позволяют внедрить конфигурацию в новые репозитории.
В результате ChainDrop движется сразу по двум направлениям. Через npm червь заражает опубликованные пакеты, не меняя исходный репозиторий. Через GitHub он добавляет команды запуска в служебные файлы веток. Оба механизма помогают продолжать цепочку заражений после кражи учётных данных.
Дополнительный риск создают автоматизированные конвейеры CI/CD. Многие проекты разрешают при сборке подтягивать свежие исправления зависимостей. Если заражённая версия подходит под диапазон версий, указанный в проекте, система сборки может скачать её автоматически. Разработчику не требуется вручную менять исходный код или самостоятельно обновлять пакет.
После обнаружения кампании заражённые версии быстро удалили из npm. Однако проверять нужно не только названия библиотек. Важно сравнивать номера установленных версий со списком скомпрометированных выпусков, поскольку заражение затронуло конкретные версии пакетов. Перечень пострадавших компонентов и их номеров опубликовала компания SafeDep.
При подозрении на компрометацию разработчикам рекомендуют искать незнакомые .claude/settings.json и .vscode/tasks.json, особенно если сотрудники проекта не создавали их самостоятельно. Проверка одной основной ветки недостаточна. Вредоносная конфигурация могла попасть в любую ветку, доступную через украденные полномочия GitHub.
Удаление подозрительных файлов само по себе проблему не решает. ChainDrop специально собирает токены npm, данные GitHub, облачные ключи и другие секреты, поэтому найденные на заражённой машине учётные данные следует считать скомпрометированными. Даже после очистки репозитория ранее украденный токен может сохранять права на публикацию пакетов или доступ к другим проектам.
Кампания также меняет требования к проверке служебных файлов внутри репозиториев. Конфигурация среды разработки способна запускать команды, поэтому её нельзя воспринимать как безобидные настройки интерфейса. .vscode/tasks.json, .claude/settings.json и другие файлы с возможностью выполнения команд требуют такой же проверки, как скрипты сборки и остальные части проекта, способные запускать код.
Отдельного внимания требуют способы публикации пакетов. Использование доверенной публикации через GitHub Actions позволяет сократить зависимость от долгоживущих npm-токенов с широкими правами. ChainDrop как раз рассчитывает на секреты, которые можно украсть один раз, а затем использовать для изменения множества пакетов.
Главная проблема ChainDrop связана с разрывом между тем, что разработчик видит в исходном репозитории, и тем, что фактически получает из npm. Проверка GitHub сама по себе больше не гарантирует, что опубликованный архив содержит те же файлы. В кампании 4 августа злоумышленники совместили эту особенность с автоматическим выполнением конфигурации VS Code и Claude Code и сумели заразить 444 пакета, не полагаясь на один привычный путь через вредоносные коммиты.