Пакет jscrambler, который разработчики используют для интеграции обфускации JavaScript-кода в сборочные конвейеры, стал звеном в цепочке поставок после публикации вредоносной версии 8.14.0. Злоумышленник добавил скрытые нативные исполняемые файлы, которые запускаются в момент установки пакета менеджером npm, задолго до того, как разработчик вызовет какой-либо код приложения. Инцидент затронул не только рабочие станции, но и системы непрерывной интеграции (CI), где jscrambler часто выполняется автоматически.
Описание
Скомпрометированный релиз вышел 11 июля 2026 года. По данным компании Socket, специализирующейся на безопасности Open Source, вредоносная активность была выявлена через шесть минут после публикации. Статистика еженедельных загрузок пакета составляет около 15,8 тысяч, однако точное число установивших опасную версию пока неизвестно.
Версия 8.14.0 внесла ряд новшеств, отсутствовавших в предыдущем чистом релизе 8.13.0. В частности, появился недокументированный хук preinstall, который вызывает файл dist/setup.js. Также были добавлены файлы dist/setup.js и dist/intro.js, а также платформенно-специфичные бинарные файлы для Linux, macOS и Windows, упакованные в обфусцированный контейнер с сигнатурой CSI. Ни один из этих файлов не присутствовал в версии 8.13.0.
Механизм заражения построен так, что для выполнения вредоносной нагрузки достаточно просто установить пакет. Хук preinstall запускает setup.js ещё до того, как будет выполнена основная логика пакета. Скрипт setup.js загружает контейнер intro.js, который на самом деле не является JavaScript-файлом, а представляет собой бинарный архив объёмом около 7,8 мегабайт. В архиве упакованы сжатые gzip исполняемые файлы: для Linux (x86-64), Windows (x86-64) и macOS (arm64). Скрипт определяет операционную систему, распаковывает соответствующий бинарник во временную папку со случайным именем, скрывая файл, и запускает его в фоновом режиме с атрибутами detached и windowsHide.
Вредоносные бинарные файлы написаны на Rust и выполняют функцию похитителя информации, нацеленного в первую очередь на разработчиков и операторов облачных систем. Подробный анализ содержимого показал, что конфиденциальные строки внутри бинарников зашифрованы по алгоритму ChaCha20-Poly1305 - каждый элемент ключом и одноразовым номером шифруется отдельно, а дешифровка самоверифицируется за счёт аутентификационной метки. Исследователям удалось восстановить около 2400 таких строк.
Целевой охват вредоносной программы крайне широк. В область интересов входят криптовалютные кошельки: расширения браузеров MetaMask, Trust Wallet, Coinbase Wallet, Phantom. Анализ конфигурации содержит ключи для извлечения сид-фраз и доступа к хранилищам типа HD Key Tree. Особое внимание уделено AI-ассистентам и конфигурациям MCP (Model Context Protocol): Claude Desktop, Cursor, Windsurf, Zed, VS Code. Хищник собирает учётные данные от облачных сервисов GCP, AWS и Azure - токены метаданных, ключи доступа, файлы аутентификации. Также перечисляются приложения для общения: Discord, Slack, Telegram Desktop. Среди целей - браузеры на основе Chromium, Firefox, игровой клиент Steam, системная связка ключей KDE KWallet. Для повышения привилегий используется sudo с передачей пароля через стандартный ввод, а также systemd-run. Для закрепления в системе предусмотрена установка systemd-юнитов, записей в crontab и LaunchAgents на macOS.
После сбора данных программа отправляет их на сервер злоумышленников по TLS, используя POST-запрос с multipart/form-data. Статический анализ выявил явный URL /upload в HTTP-заголовках. Кроме того, бинарник выполняет запросы к API облачных метаданных и Kubernetes для дальнейшего распространения.
После обнаружения первой вредоносной версии тот же злоумышленник в течение примерно трёх часов опубликовал ещё четыре релиза: 8.16.0, 8.17.0, 8.18.0 и 8.20.0. Они перемежались попытками исправления со стороны разработчиков. Содержимое полезной нагрузки (intro.js и бинарные файлы) осталось идентичным, но изменился способ доставки. В версии 8.18.0 хук preinstall был удалён - теперь вредоносный код встраивается как самоисполняющаяся функция в файлы dist/index.js и dist/bin/jscrambler.js, что приводит к его выполнению при импорте пакета или запуске CLI, а не при установке. Такой приём обходит проверки, которые анализируют только preinstall/postinstall скрипты, а также позволяет запуску произойти даже при использовании флага --ignore-scripts. Версии 8.18.0 и 8.20.0 также объявили самозависимость от jscrambler (^8.17.0), что при установке транзитивно подтягивало скомпрометированный релиз.
Чистыми версиями, помимо 8.13.0, являются 8.15.0 и 8.22.0. Разработчики Jscrambler подтвердили инцидент в своём бюллетене безопасности. По результатам расследования установлено, что злоумышленник получил доступ к учётной записи публикации npm. Компания отозвала и заменила учётные данные, отозвала скомпрометированные релизы и усилила контроль над процессом публикации.
Пользователям, которые устанавливали пакет jscrambler в версию 8.14.0 или любую из последующих заражённых, следует немедленно удалить её, сменить все учётные данные и токены, которые были доступны в среде выполнения (включая секреты CI/CD, переменные окружения, ключи доступа к облаку). Необходимо также проверить журналы установки на предмет выполнения dist/setup.js и использования временных каталогов. В качестве меры предосторожности рекомендуется обновить пакет до версии 8.22.0 или зафиксировать её в зависимостях проекта до официального релиза чистой версии.
Индикаторы компрометации
Malicious npm package
- jscrambler@8.14.0
- jscrambler@8.16.0
- jscrambler@8.17.0
- jscrambler@8.18.0
- jscrambler@8.20.0
SHA256
- a41a523ef9517aab37ed6eea0ec881821bdcb7aefcb5c5f603adc7907f868c86
- a742de963f14a92d24ebcbc7b44ac867e23a20d31d1b0094a13a4f83287f4e60
- b7ca95d1b23c8e67416a25cedf741de0917c2096bbc9d24649eea7853d054903
- bba32ddeab075a5e5015eec50f5d2af364c95b848732c714aea6b6baf78f49f0
- c8fd47d36bdf7c825378593ab82ed8c24d1dc52e26b507812393e24e1d5201fd
- fbbcf4d8f98168f78f5c0c47a9ae56d59ec8ac84a7c9ca6b797fedfb8d62d2bd