Новости
npm 12 перестала запускать install-скрипты по умолчанию
Платформа отключила автоматический запуск хуков установки — прямая защита от того класса атак, что ударил по keyv и cacheable.
Один взломанный аккаунт разработчика — и вредоносный код за минуты разъехался по пакетам, которые скачивают сотни миллионов раз в неделю. 4 августа 2026 года атаковали популярные npm-библиотеки keyv и cacheable: злоумышленники подменили их новые версии, а спрятанный в пакете скрипт запускался автоматически при установке и крал токены доступа. Разбираем, как устроена атака на цепочку поставок и что из этого следует для всех, кто устанавливает чужой код.

Коротко: 4 августа 2026 года злоумышленники захватили аккаунт мейнтейнера и опубликовали заражённые версии npm-пакетов keyv, cacheable и ещё нескольких — суммарно более 500 млн загрузок в неделю. Вредоносный preinstall-скрипт запускался при установке, крал токены npm, GitHub, AWS и Vault и с их помощью заражал новые пакеты. По данным Endor Labs, скомпрометированы 1136 версий в 384 пакетах.
4 августа 2026 года началась одна из крупнейших за год атак на цепочку поставок в экосистеме npm — репозитории пакетов для JavaScript и Node.js. Под удар попали широко используемые библиотеки кэширования keyv и cacheable, а также связанные с ними пакеты. Первые заражённые версии появились примерно в 9 часов утра по UTC, и в течение нескольких минут тот же вредоносный код разошёлся по девяти пакетам одного автора.
Масштаб определяется не числом пакетов, а их популярностью. По оценке компании Endor Labs, только «стартовые» библиотеки суммарно скачивают более 500 млн раз в неделю:
| Пакет | Заражённая версия | Загрузок в неделю |
|---|---|---|
| keyv | 6.0.0 | ~154 млн |
| flat-cache | 6.1.24 | ~150 млн |
| file-entry-cache | 11.1.6 | ~147 млн |
| cacheable | 2.5.1 | ~7,8 млн |
| cache-manager | 7.2.10 | ~4,2 млн |
Эти библиотеки почти никогда не ставят вручную — они приходят как зависимости зависимостей в тысячах веб-приложений и инструментов сборки. Именно поэтому даже несколько часов, пока заражённые версии были доступны, дали злоумышленникам огромный охват.
Точкой входа стал захват аккаунта мейнтейнера. Исследователи из Wiz и Socket установили, что атакующие получили контроль над учётной записью разработчика, отвечавшего за keyv и cacheable, отправили вредоносные коммиты прямо в главную ветку (main) репозитория и тут же выпустили новые релизы.
Опасной атаку сделала одна деталь: релизы публиковались через официальный конвейер trusted publishing на GitHub Actions (механизм OIDC, при котором npm доверяет сборкам из репозитория без ручного ввода токена). В результате заражённые пакеты уходили в npm с действительной подписью происхождения (provenance) — то есть выглядели полностью легитимно, как обычная автоматическая публикация.
Сам вредонос прятался в манифесте пакета. В файл package.json добавляли хук установки:
"preinstall": "node setup.mjs"Скрипт с хуком preinstall запускается автоматически, ещё до кода приложения, как только пакет устанавливается командой npm install. Загрузчик setup.mjs скачивал с GitHub «чистый» бинарник среды выполнения Bun 1.3.13, а затем запускал через него обфусцированную полезную нагрузку второй ступени размером около 727 КБ. Пользователь при этом не видел ничего, кроме обычной установки зависимостей.
Заражение происходило не при запуске программы, а на этапе установки пакета. Хук preinstall выполняет код автоматически — открывать или запускать что-то вручную жертве не требовалось.
Полезная нагрузка второй ступени — это похититель учётных данных (credential stealer). По данным Endor Labs, он собирал с заражённой машины и CI-серверов:
Дальше вредонос вёл себя как червь: похищенными токенами npm он публиковал заражённые версии уже других пакетов, до которых дотягивался. Именно так атака вышла далеко за пределы первых библиотек. Endor Labs на момент разбора подтвердила 1136 вредоносных версий в 384 пакетах; среди пострадавших организаций называют ServiceTitan, Ornikar, Qlik и другие. Исследователи связывают кампанию с семейством самораспространяющегося вредоноса Shai-Hulud (его «облегчённой» вариацией).
Такая схема — саморазмножение через украденные ключи публикации — отличает современные атаки на цепочку поставок от разовых закладок. Похожий приём мы разбирали в материалах про вредоносные гемы в RubyGems и поддельные ZIP-архивы на GitHub: вредонос всё чаще едет не отдельным файлом, а внутри легитимного с виду пакета.
Главный урок инцидента прямо касается темы нашего сайта: пакет — это тоже файл, который может выполнять код. Устанавливая зависимость, вы фактически запускаете чужой архив с манифестом package.json, а хук установки способен выполнить произвольную команду ещё до старта вашего приложения. Действительная подпись и миллионы загрузок при этом не гарантируют безопасность конкретной версии.
Что стоит сделать, если вы разработчик или используете инструменты на Node.js:
package-lock.json, yarn.lock) и логах CI.--ignore-scripts, чтобы хуки вроде preinstall не выполнялись автоматически. Подробнее о том, зачем платформа блокирует эти скрипты по умолчанию, — в новости про npm 12, которая перестала запускать install-скрипты.Обычным пользователям Node.js-приложений отдельных действий, как правило, не требуется — атака нацелена на разработчиков и серверы сборки. Но общий принцип универсален и для любых загрузок: опасность несёт не расширение файла, а то, что этот файл делает при открытии или установке. Базовые правила безопасной работы с файлами и вложениями собраны в разделе безопасность файлов.