Злоумышленники скомпрометировали npm-пакет Axios — один из самых популярных HTTP-клиентов в экосистеме JavaScript с более чем 100 миллионами загрузок в неделю. Атакующие взломали аккаунт ведущего мейнтейнера проекта и опубликовали две заражённые версии, содержащие кроссплатформенный троянец удалённого доступа (RAT). Троянец поражает macOS, Windows и Linux, после чего уничтожает собственные следы. Заражённые версии уже удалены из реестра npm.
Как произошла атака
Компанию StepSecurity первой обнаружила инцидент года. Атакующие захватили npm-аккаунт ведущего мейнтейнера Axios «jasonsaayman», сменив его электронную почту на анонимный адрес ProtonMail. Используя скомпрометированные учётные данные, злоумышленники вручную опубликовали заражённые пакеты через командную строку npm, полностью обойдя штатный конвейер GitHub Actions с криптографической OIDC-верификацией.
Все легитимные релизы Axios в ветке 1.x публикуются через GitHub Actions с привязкой к верифицированному рабочему процессу. Заражённая версия 1.14.1 не имеет ни соответствующего коммита, ни тега в репозитории Axios на GitHub — она существовала только в реестре npm.
OIDC (OpenID Connect) — протокол аутентификации, позволяющий npm криптографически привязать публикацию пакета к конкретному рабочему процессу в GitHub Actions. Ручная публикация в обход этого механизма — признак компрометации.
Были опубликованы две вредоносные версии с интервалом 39 минут: axios@1.14.1 (для ветки 1.x) и axios@0.30.4 (для устаревшей ветки 0.x). Одновременное заражение обеих веток максимизировало охват атаки: любой проект с диапазоном версий ^1.14.0 или ^0.30.0 мог автоматически получить заражённый пакет при очередном запуске
npm install
Механизм заражения
Сам код Axios злоумышленники не изменяли. Вместо этого в файл package.json добавлена поддельная зависимость plain-crypto-js@4.2.1, которая нигде не импортируется в исходном коде библиотеки. У настоящего Axios всего три зависимости: follow-redirects, form-data и proxy-from-env. Появление четвёртой — однозначный индикатор подмены.
Единственное назначение plain-crypto-js — выполнение postinstall-скрипта. При запуске
npm install axiosменеджер пакетов автоматически разрешает дерево зависимостей, устанавливает plain-crypto-js@4.2.1 и запускает её postinstall-хук, который активирует дроппер (setup.js, 4209 байт).
postinstall-скрипт — хук жизненного цикла npm-пакета, который автоматически выполняется сразу после установки. Разработчики используют его для компиляции нативных модулей или настройки конфигурации, но злоумышленники часто применяют этот механизм для запуска вредоносного кода без ведома пользователя.
Атака готовилась заранее. За 18 часов до публикации заражённых версий Axios злоумышленники разместили в реестре npm чистую версию plain-crypto-js@4.2.0 — полную копию легитимной библиотеки crypto-js с тем же описанием и указанием того же автора (Evan Vosberg). Версия 4.2.0 не содержала вредоносного кода и служила исключительно для создания истории публикаций, чтобы учётная запись не выглядела подозрительно новой для автоматических сканеров безопасности. Вредоносная версия 4.2.1 появилась в реестре 30 марта в 23:59 UTC — за две минуты до публикации заражённого Axios.
Платформенные полезные нагрузки
Дроппер определяет операционную систему через os.platform() и запускает один из трёх сценариев заражения.
macOS
На macOS дроппер загружает вредоносный бинарник в каталог /Library/Caches/com.apple.act.mond. Путь выбран не случайно: /Library/Caches/ — системный каталог, который редко проверяется при расследовании инцидентов, а имя файла com.apple.act.mond имитирует стандартную схему именования фоновых процессов Apple. Файл получает права 770 и запускается в фоне через /bin/zsh.
Windows
На Windows цепочка заражения включает три этапа. Сначала дроппер определяет путь к PowerShell и копирует его в %PROGRAMDATA%\wt.exe, маскируя интерпретатор под исполняемый файл Windows Terminal. Затем в каталоге временных файлов создаётся VBScript, который запускает полностью скрытое окно cmd.exe (без какого-либо интерфейса). Командный сервер возвращает троянский скрипт PowerShell, который сохраняется по пути %TEMP%\6202033.ps1 и выполняется с параметрами -ExecutionPolicy Bypass и -WindowStyle Hidden.
Linux
На Linux дроппер через execSync (Node.js) загружает скрипт /tmp/ld.py и запускает возвращённый троянец в фоновом режиме через nohup.
Во всех трёх случаях троянец подключается к командному серверу sfrclak[.]com (проверка на VirusTotal) на порту 8000, загружает полезную нагрузку второго этапа и обеспечивает постоянное присутствие в системе.
Дроппер — вредоносная программа, основная задача которой — доставить и запустить на целевой системе другой вредоносный компонент (полезную нагрузку). Сам дроппер обычно не выполняет деструктивных действий и удаляет себя после выполнения.
Самоуничтожение следов
После заражения дроппер удаляет файл setup.js и заменяет вредоносный package.json заранее подготовленной чистой заглушкой (файл package.md переименовывается в package.json). Разработчик, проверяющий содержимое каталога node_modules после заражения, не обнаружит ничего подозрительного — все файлы выглядят нормально.
Реакция сообщества и текущий статус
Компания Socket зафиксировала аномалию через шесть минут после публикации вредоносного пакета. Администрация npm удалила заражённые версии Axios примерно через три часа (около 03:15 UTC 31 марта), а пакет plain-crypto-js заменён заглушкой безопасности. На момент удаления версия axios@1.14.1 была доступна в реестре около двух часов 53 минут.
Мейнтейнеры Axios подтвердили инцидент в GitHub и занимаются восстановлением безопасного процесса публикации. По предварительным данным, атакующим удалось воспользоваться долгоживущим классическим npm-токеном доступа, который хранился параллельно с механизмом доверенной публикации.
Как проверить свой проект
Для проверки установленной версии Axios выполните:
npm list axios
Если в выводе отображается версия 1.14.1 или 0.30.4 — проект затронут. Дополнительно проверьте наличие вредоносной зависимости:
ls node_modules/plain-crypto-js
Также рекомендуется проверить файл package-lock.json:
grep -r "plain-crypto-js" package-lock.json
Рекомендации
Разработчикам необходимо откатиться на безопасные версии: axios@1.14.0 (ветка 1.x) или axios@0.30.3 (ветка 0.x). Зафиксируйте точную версию в package.json без использования символа ^ или ~.
Если заражённая версия была установлена, следует считать систему скомпрометированной. В этом случае необходимо сменить все учётные данные: npm-токены, ключи облачных сервисов, SSH-ключи, пароли баз данных. Проверьте сетевые логи на наличие исходящих подключений к домену sfrclak[.]com и IP-адресу 142.11.206.73 (порт 8000). Для критически важной инфраструктуры рассмотрите полную переустановку системы.
В конвейерах CI/CD используйте флаг --ignore-scripts для предотвращения автоматического выполнения postinstall-скриптов:
npm ci --ignore-scripts

