Новости · Кибербезопасность

Взлом npm-пакетов keyv и cacheable: крупная атака на цепочку поставок

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

6 августа 2026 Редакция LoadFile Чтение 7 мин
Ряд блестящих кубов-пакетов на конвейере, один в центре треснул и светится красным, рассыпаясь тёмными частицами на соседние

Коротко: 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 млн раз в неделю:

ПакетЗаражённая версияЗагрузок в неделю
keyv6.0.0~154 млн
flat-cache6.1.24~150 млн
file-entry-cache11.1.6~147 млн
cacheable2.5.1~7,8 млн
cache-manager7.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 (позволяют публиковать новые версии пакетов);
  • токены GitHub, включая токены GitHub Actions и приложений;
  • ключи доступа AWS;
  • токены HashiCorp Vault — хранилища секретов.

Дальше вредонос вёл себя как червь: похищенными токенами npm он публиковал заражённые версии уже других пакетов, до которых дотягивался. Именно так атака вышла далеко за пределы первых библиотек. Endor Labs на момент разбора подтвердила 1136 вредоносных версий в 384 пакетах; среди пострадавших организаций называют ServiceTitan, Ornikar, Qlik и другие. Исследователи связывают кампанию с семейством самораспространяющегося вредоноса Shai-Hulud (его «облегчённой» вариацией).

Такая схема — саморазмножение через украденные ключи публикации — отличает современные атаки на цепочку поставок от разовых закладок. Похожий приём мы разбирали в материалах про вредоносные гемы в RubyGems и поддельные ZIP-архивы на GitHub: вредонос всё чаще едет не отдельным файлом, а внутри легитимного с виду пакета.

Что это значит для тех, кто ставит зависимости

Главный урок инцидента прямо касается темы нашего сайта: пакет — это тоже файл, который может выполнять код. Устанавливая зависимость, вы фактически запускаете чужой архив с манифестом package.json, а хук установки способен выполнить произвольную команду ещё до старта вашего приложения. Действительная подпись и миллионы загрузок при этом не гарантируют безопасность конкретной версии.

Что стоит сделать, если вы разработчик или используете инструменты на Node.js:

  1. Проверьте версии. Зафиксируйте (pin) зависимости на версии, выпущенные до 4 августа 2026 года, и поищите заражённые версии из таблицы выше в своих lock-файлах (package-lock.json, yarn.lock) и логах CI.
  2. Ротируйте секреты. Если заражённая версия могла попасть на машину разработчика или в сборочный конвейер, смените токены npm, GitHub, ключи AWS и Vault — их могли украсть.
  3. Отключите скрипты установки в CI. Ставьте зависимости с флагом --ignore-scripts, чтобы хуки вроде preinstall не выполнялись автоматически. Подробнее о том, зачем платформа блокирует эти скрипты по умолчанию, — в новости про npm 12, которая перестала запускать install-скрипты.

Обычным пользователям Node.js-приложений отдельных действий, как правило, не требуется — атака нацелена на разработчиков и серверы сборки. Но общий принцип универсален и для любых загрузок: опасность несёт не расширение файла, а то, что этот файл делает при открытии или установке. Базовые правила безопасной работы с файлами и вложениями собраны в разделе безопасность файлов.

Источники

Читайте также