Источник: ReversingLabs Blog — https://www.reversinglabs.com/blog/31-red-hat-cloud-service-npm-packages-backdoored-in-72-seconds
По данным ReversingLabs, 1 июня 2026 года злоумышленник опубликовал вредоносные версии 31 npm-пакета из JavaScript-экосистемы Hybrid Cloud Console компании Red Hat. Важнее самого количества пакетов другой сигнал: затронутые релизы происходили из двух разных GitHub-репозиториев, но были опубликованы в одном и том же npm scope. По оценке RL, это больше похоже на компрометацию учётных данных для публикации в npm, чем на обычный взлом исходного репозитория.
Для расследования инцидентов в цепочке поставок ПО это принципиальная разница. Если атакующий способен публиковать пакеты напрямую в реестр, чистый GitHub-репозиторий ещё не означает, что установленная пользователями версия пакета была безопасной.
Что произошло#
Согласно ReversingLabs, вредоносные версии 31 пакета были опубликованы между 10:54:09 и 10:55:21 UTC. Суммарно эти пакеты насчитывают около 9,8 миллиона загрузок и охватывают UI-компоненты, API-клиенты, инструменты сборки, утилиты конфигурации и MCP-серверы в JavaScript-экосистеме Hybrid Cloud Console.
RL перечисляет среди затронутых пакетов @redhat-cloud-services/chrome, @redhat-cloud-services/frontend-components, @redhat-cloud-services/insights-client, @redhat-cloud-services/rbac-client, @redhat-cloud-services/vulnerabilities-client, @redhat-cloud-services/compliance-client и другие пакеты из того же npm scope.
Временная картина стала первой важной подсказкой. Тридцать одна публикация за 72 секунды не похожа на ручную работу, когда оператор поочерёдно изменяет и выпускает пакеты. RL описывает это как автоматизированную публикацию по сценарию: заражённые архивы, вероятно, были подготовлены заранее и затем отправлены одним пакетом.
Вторая подсказка — характер изменений. По данным ReversingLabs, каждый затронутый пакет отличался от предыдущей чистой версии одинаковым набором модификаций:
- в
package.jsonдобавлялся скриптpreinstall, запускающийindex.js; - штатный файл
index.jsзаменялся вредоносной обфусцированной нагрузкой; - остальные файлы не изменялись.
Разница в коде была минимальной, а последствия — масштабными. Скрипт preinstall выполняется во время установки пакета, ещё до того, как проект начнёт его импортировать. Фактически точкой исполнения становится сам процесс установки зависимостей.
Почему меняется модель риска для цепочки поставок#
Это не просто история про очередной вредоносный пакет в npm. Ключевая проблема — путаница в границах доверия.
Многие разработчики воспринимают исходный репозиторий как главный источник истины. Это полезно, но недостаточно. На практике установка обычно доверяет артефакту из реестра пакетов. Если учётные данные для публикации скомпрометированы, злоумышленнику не обязательно менять исходный код в GitHub, pull request’ы, историю задач или журналы CI/CD. Достаточно выпустить версию с привычным namespace и именем пакета, которая отличается от исходников, на которые рассчитывают пользователи.
ReversingLabs отмечает, что затронутые пакеты относятся к двум GitHub-репозиториям: RedHatInsights/frontend-components и RedHatInsights/javascript-clients. Именно это распространение через несколько репозиториев позволяет RL предполагать компрометацию на уровне npm scope. Если вывод верен, расследование должно сосредоточиться на доступе сопровождающих, токенах, процессе публикации и механизмах защиты реестра, а не только на очистке репозиториев.
Конструкция вредоносного кода также выглядит заранее продуманной. RL описывает многоуровневую цепочку обфускации: слой ROT-N в стиле шифра Цезаря, расшифровку AES-128-GCM и нагрузку, обработанную через obfuscator.io. Внешний слой собирает большую закодированную строку и выполняет её преобразование. Затем декодированный код расшифровывает два блока с помощью модуля crypto из Node.js. Один блок загружает среду выполнения Bun из официального GitHub-релиза во временный каталог. Второй содержит основную нагрузку, которая записывается во временный файл и запускается через Bun.
Важно не делать из этого вывод о проблемах в самом Bun. Судя по описанию RL, загрузка среды выполнения была лишь частью схемы доставки: злоумышленник использовал легитимный бинарный файл из легитимного источника для запуска своей нагрузки. Проблема безопасности связана с вредоносным пакетом и компрометацией процесса публикации, а не с существованием Bun.
Что проверить в первую очередь#
Первый шаг прост: выяснить, использовали ли ваши сборки, рабочие станции разработчиков, CI-раннеры, контейнерные образы или lock-файлы вредоносные версии пакетов, перечисленных ReversingLabs. Не ограничивайтесь прямыми зависимостями. Среди затронутых пакетов есть общие клиенты и frontend-компоненты, поэтому возможна транзитивная зависимость.
Практические проверки:
- просмотрите
package-lock.json,yarn.lock,pnpm-lock.yamlи журналы сборки на предмет затронутых пакетов@redhat-cloud-services/*; - сопоставьте версии и время установки с окном публикации 1 июня, указанным RL;
- проверьте журналы CI на выполнение
preinstallиз этих пакетов; - выясните, выполнялась ли установка на системах, где были доступны npm-токены, облачные учётные данные, SSH-ключи, GitHub-токены или данные доступа к внутренним реестрам пакетов;
- смените учётные данные, если исключить компрометацию среды установки невозможно;
- пересоберите артефакты из заведомо чистых версий зависимостей вместо доверия к уже существующим результатам сборки.
Наибольший риск часто несут не production-серверы. В инцидентах цепочки поставок системы сборки и рабочие станции разработчиков нередко содержат более ценные секреты, чем контейнеры с приложениями. Вредоносному preinstall не требуется запуск приложения — достаточно установки зависимостей в подходящей среде.
Для команд, уже работающих над целостностью зависимостей, этот случай показывает, что происхождение пакетов должно быть рабочим механизмом контроля, а не формальностью. Trusted publishing, короткоживущие токены, обязательная двухфакторная защита публикаций в реестре, проверка артефактов и аудит lock-файлов направлены именно на ту точку риска, которую описывает RL: кто публикует пакет, что именно опубликовано и соответствует ли артефакт ожидаемому исходному коду.
Материалы по теме:
- https://gigatap.top/en/articles/openssfs-april-signal-make-security-artifacts-operational
- https://gigatap.top/en/articles/100-package-test-coverage-is-the-point-not-the-slogan
Чего пока нельзя утверждать#
Исходный материал позволяет уверенно говорить о вредоносных версиях npm-пакетов и вероятной компрометации доступа к публикации на уровне scope. Однако представленных данных недостаточно, чтобы установить, какие именно учётные данные были украдены, каким способом их получили злоумышленники, были ли скомпрометированы все загрузившие пакеты пользователи и какие данные смогла собрать финальная нагрузка.
Эта неопределённость важна. Миллионы суммарных загрузок пакетов не означают миллионы взломанных систем. В статистику входят исторические загрузки, автоматические зеркала, работа кэшей, активность CI/CD и повторные установки. Реальный масштаб воздействия зависит от того, кто установил вредоносные версии в период атаки и какие секреты были доступны в этих средах.
Стоит также разделять целостность исходников и целостность пакетов. Репозиторий может оставаться чистым, а артефакты в реестре — быть подменёнными. Именно поэтому проверки безопасности open source должны охватывать весь путь релиза: доступ сопровождающих, права публикации в реестре, правила CI/CD, скрипты установки, различия между артефактами и исходниками, а также поведение после установки.
Главный вывод прост. Относитесь к правам публикации пакетов так же серьёзно, как к доступу в production. Токен с правами на уровне scope способен превратить доверенные имена пакетов в канал выполнения вредоносного кода быстрее, чем большинство команд успеет заметить проблему вручную. В этом случае, по данным RL, на всё ушло 72 секунды.