17 июня 2026 года специалисты компании Socket зафиксировали масштабную атаку на цепочку поставок программного обеспечения, затронувшую пакеты из пространства имён @mastra. Злоумышленник, действовавший через учётную запись npm ehindero, в течение короткого промежутка времени опубликовал 141 вредоносную версию пакетов Mastra. Атака представляет серьёзную угрозу для тысяч проектов, поскольку основная библиотека @mastra/core загружается более 918 тысяч раз в неделю. Жертвами могут стать разработчики, использующие Mastra в своих приложениях, а также сборочные конвейеры CI/CD.
Описание
Сам по себе код опубликованных пакетов @mastra/* не содержал изменений - он остался идентичным последней легитимной сборке. Вредоносная функция была внедрена через транзитивную зависимость. В каждый манифест package.json была добавлена строка с зависимостью от пакета easy-day-js, который представляет собой typosquatting (имитацию) популярной библиотеки dayjs. Пакет easy-day-js был опубликован днём ранее, 16 июня, с другого аккаунта (sergey2016). Версия 1.11.21 была чистой, а версия 1.11.22 содержала вредоносный сценарий postinstall, который запускался автоматически при выполнении команды npm install. Таким образом, любой разработчик, установивший одну из скомпрометированных версий @mastra/*, немедленно загружал и исполнял вредоносное ПО.
Согласно анализу исследователей Socket, загрузчик, написанный на Node.js и обфусцированный с помощью obfuscator.io, выполнял следующие действия. Сначала он отключал проверку сертификатов TLS (параметр NODE_TLS_REJECT_UNAUTHORIZED = 0), затем отправлял на сервер управления метку жертвы, записывая имя текущего каталога во временный файл .pkg_history. После этого он загружал второй этап (полезную нагрузку) с адреса 23.254.164.92:8000, сохранял её в случайный файл в папке TEMP и запускал как фоновый процесс, передавая ему адрес другого сервера для эксфильтрации данных. Сам загрузчик удалял себя, затрудняя криминалистический анализ.
Второй этап представлял собой кросс-платформенный имплант размером около 41 КБ, который не ограничивался простым сбором данных, а создавал механизмы закрепления в системе. Он распространялся на три основные операционные системы. На Windows он добавлял значение реестра NvmProtocal в автозагрузку текущего пользователя, скрываясь в каталоге C:\ProgramData\NodePackages\ с именами protocal.cjs и config.json. На macOS создавал агент запуска LaunchAgent с меткой com.nvm.protocal, который выполнял скрипт из ~/Library/NodePackages/protocal.cjs. На Linux устанавливал systemd-модуль пользовательского уровня ~/.config/systemd/user/nvmconf.service, запускавший тот же скрипт. Все эти имена маскировались под легитимные инструменты управления Node.js (NVM), чтобы не вызывать подозрений у разработчиков.
После установки закрепления имплант отправлял на сервер управления стартовый маяк, содержащий информацию о системе (имя хоста, архитектура, платформа, список процессов и установленных приложений). Затем он переходил в цикл опроса, ожидая команд от оператора. Сервер мог вернуть произвольный код для выполнения через встроенные раннеры (Node.js или Shell). Это означало, что атакующие имели возможность в любой момент доставить на скомпрометированную машину дополнительные модули, в том числе для кражи паролей, криптовалютных ключей или других конфиденциальных данных.
В текущей версии имплант уже собирал историю браузера (Chrome, Edge, Brave) путём копирования и чтения SQLite-файла History, а также инвентаризировал установленные расширения криптовалютных кошельков. Он содержал жёстко заданный список из 166 идентификаторов расширений, включая MetaMask, Phantom, Coinbase Wallet, Binance Wallet, TronLink и другие. Имплант проверял, какие из этих расширений присутствуют в профилях браузеров, и отправлял на сервер их идентификаторы и пути. Однако в обнаруженном образце он не копировал данные самих кошельков (базы LevelDB), а только составлял перечень. Тем не менее из-за возможности динамической доставки команд угроза кражи средств остаётся высокой.
Эксфильтрация осуществлялась по протоколу HTTPS с использованием поддельного User-Agent, маскирующего трафик под устаревший браузер Internet Explorer 8. Для шифрования использовался самоподписанный сертификат - обе стадии отключали проверку TLS, что позволяло злоумышленникам использовать любой сертификат без риска блокировки сертификационными центрами.
Socket зафиксировал вредоносный пакет easy-day-js версии 1.11.22 уже через шесть минут после его публикации. Пользователи Socket были автоматически защищены: установка скомпрометированных версий блокировалась до выполнения postinstall-сценария. Компания опубликовала полный список затронутых пакетов и версий на специальной странице кампании.
Любая система, на которой была выполнена установка одной из вредоносных версий @mastra/*, должна считаться потенциально скомпрометированной. Поскольку полезная нагрузка запускалась уже на этапе npm install, уязвимыми оказались не только рабочие станции разработчиков, но и сборочные серверы, агенты CI/CD и любые окружения, где выполнялась автоматическая установка зависимостей. Разработчикам, которые используют Mastra, рекомендуется немедленно проверить наличие пакета easy-day-js в lock-файлах (package-lock.json, yarn.lock, pnpm-lock.yaml) и, в случае обнаружения, перейти на последнюю чистую версию, опубликованную до атаки (с более низким номером патча). Важно также удалить остаточные файлы закрепления в соответствии с операционной системой, ротировать все токены, которые могли оказаться в окружении установки (npm-токены, ключи облачных провайдеров, SSH-ключи), и, если на машине использовались расширения криптовалютных кошельков, рассмотреть миграцию средств на новые кошельки, созданные на чистом устройстве.
Усиление контроля за жизненным циклом зависимостей - установка с отключёнными сценариями (npm install --ignore-scripts), использование белых списков пакетов и задержка принятия свежеопубликованных версий - позволит снизить риск повторения подобных атак. Данный инцидент показал, что даже проверенные пространства имён могут быть скомпрометированы через учётные записи с легитимными правами публикации.