Атака на npm-пакеты: угрозы цепочки поставок ПО
В начале августа 2026 года злоумышленники захватили GitHub-аккаунт мейнтейнера библиотеки keyv — небольшого пакета для хранения данных, который загружается из реестра npm около 127 миллионов раз в неделю. За несколько часов в реестре появились заражённые версии keyv и связанных кэширующих пакетов. Компания Aikido зафиксировала не менее 868 скомпрометированных пакетов в 1 381 версии с суммарным объёмом более двух миллиардов ежемесячных установок. Независимое расследование JFrog охватило свыше 400 пакетов и 1 700 заражённых версий.
Главная особенность атаки — не масштаб распространения, а механизм доверия. Вредоносные релизы были подписаны валидными криптографическими подписями провенанса. Атакующие не подделали сертификаты — они получили их законным путём, запустив вредоносный код через собственный GitHub Actions workflow скомпрометированного мейнтейнера. Для любой системы аудита цепочки поставок заражённая сборка выглядела подлинной.
Как работал червь и почему он распространился так быстро
Механизм распространения объясняет масштаб инцидента. Атакующие внесли изменения в репозитории мейнтейнера, выпустили новые версии пакетов, и система npm сгенерировала легитимный провенанс, поскольку сборка прошла через доверенный pipeline. В одном из задокументированных JFrog случаев червь запросил OIDC-токен, обменял его на токен публикации и создал Sigstore-bundle через Fulcio и Rekor — вредоносный архив получил провенанс из доверенного контекста workflow.
Попав в среду разработчика или на сборочный сервер, вредоносная нагрузка собирала все доступные учётные данные, после чего использовала найденные npm-токены для заражения других пакетов, которые контролировала жертва. Каждый скомпрометированный мейнтейнер превращался в невольный узел распространения. Aikido наблюдала появление десятков новых заражённых пакетов каждые несколько минут.
Среди подтверждённых жертв оказались корпоративные npm-пакеты, связанные с Deliveroo, Qlik и Picsart. Разработчики этих компаний не устанавливали keyv намеренно — они зависели от других пакетов, которые зависели от него через несколько уровней транзитивных зависимостей.
Реальной целью атаки были не кэширующие библиотеки. По данным JFrog и Wiz, вредоносный код извлекал ключи доступа к облачной инфраструктуре, секреты CI-систем и токены для аутентификации в производственных системах. Пакет был лишь транспортным средством.
Помимо кражи данных, червь закреплялся на машинах разработчиков. Wiz обнаружила, что вредоносная нагрузка размещала файлы в двух директориях: одной для Visual Studio Code и одной с именем .claude — рабочей директории AI-агента Claude Code от Anthropic. Это означало, что код мог исполняться при открытии заражённого проекта в редакторе или при запуске сессии AI-ассистента — не только в момент установки пакета.
Что конкретно может сделать бизнес
Атака на keyv обнажила несколько структурных уязвимостей, которые поддаются управлению на уровне политик и инструментов.
- Задержка установки зависимостей. npm начиная с версии 11.10.0 поддерживает настройку min-release-age, pnpm — minimumReleaseAge. Оба параметра позволяют отклонять версии пакетов, опубликованные недавно. Неделя задержки даёт сообществу безопасности время обнаружить заражение до того, как оно попадёт в сборки.
- Обновление до npm версии 12. В этой версии preinstall, install и postinstall скрипты отключены по умолчанию. JFrog подтвердила: на npm 12 червь keyv не исполняется в момент установки.
- Контроль идентификаций с правом публикации. Атака начиналась с одного захваченного аккаунта. Провенанс подписал заражённый код, потому что он прошёл через pipeline мейнтейнера. Надёжная многофакторная аутентификация для всех, кто имеет право публиковать пакеты, — базовый контроль.
- Приоритизация патчинга по Known Exploited Vulnerability Catalog. Адам Мейерс, руководитель Counter Adversary Operations в CrowdStrike, рекомендует использовать каталог CISA как основу для расстановки приоритетов: закрывать сначала уязвимости, подтверждённо эксплуатируемые в реальных атаках.
- Классификация CI-серверов и рабочих станций разработчиков как критических активов с соответствующими стандартами ротации учётных данных.
Отдельного внимания заслуживает скорость реагирования. По данным CrowdStrike, 88% эксплуатации уязвимостей с публичным proof-of-concept происходит в течение 48 часов после публикации кода. В 2026 году к концу июля было зарегистрировано уже около 43 000 CVE — почти столько, сколько за весь 2025 год (около 48 200). Это означает, что 30-дневные циклы патчинга физически не справляются с темпом угроз.
Параллельно формируется новое регуляторное давление. Кейн МакГлэдри, старший член IEEE, сообщил VentureBeat, что предприятия начинают переносить обязательства по безопасности на вендоров и мейнтейнеров в своих цепочках поставок через контрактные механизмы. Для любой компании, поставляющей программное обеспечение на основе открытых зависимостей, это превращает вопросы провенанса, управления идентификациями и дисциплины патчинга в потенциальные договорные риски.
GitHub как владелец npm за прошедший год усилил реестр: ввёл обязательную двухфакторную аутентификацию для публикации, отозвал старые бессрочные токены и добавил механизм trusted publishing. Тем не менее эти меры укрепили защиту от исполнения вредоносного кода после попадания в реестр сильнее, чем от получения права на публикацию. Захват аккаунта остаётся корневой причиной: атакующие входят с валидными учётными данными, а не взламывают инфраструктуру.
Практический вывод: проверьте, используют ли ваши команды настройку min-release-age в npm или minimumReleaseAge в pnpm — включение этого параметра с порогом в семь дней не требует бюджета, занимает несколько минут и закрывает основной вектор распространения подобных атак.