javascript

Axios и проблема зависимостей

  • суббота, 18 апреля 2026 г. в 00:00:08
https://habr.com/ru/articles/1024520/

Продолжаю беседы с нашим техлидом Дмитрием. Сегодня — о том, как взлом одного npm-аккаунта за 3 часа распространил RAT на 174 000 пакетов и почему стандартные инструменты вроде NPM Audit это не поймали. Разбираем инцидент с Axios: механику атаки, слепые пятна в CI/CD и то, что реально работает.

30 марта 2026: что произошло за 3 часа

30 марта 2026 года в npm появились две вредоносные версии Axios — 1.14.1 (тег latest) и 0.30.4 (тег legacy). Axios — JavaScript-библиотека для HTTP-запросов с ~100 млн загрузок в неделю и 174 000 зависимых пакетов в npm. Фактически, если проект на Node.js — с высокой вероятностью он тянет Axios транзитивно.

Злоумышленник получил доступ к npm-аккаунту jasonsaayman — ведущего мейнтейнера библиотеки. Первый признак компрометации: email аккаунта сменился с jasonsaayman@gmail.com на ifstap@proton.me, а метод публикации изменился — с доверенного OIDC-пайплайна со SLSA-провенансом на прямой CLI-publish. Оба флага автоматически поймала Elastic Security Labs через мониторинг цепочки поставок.

Вредоносные версии пробыли в реестре около 3 часов. За это время их успели скачать и задеплоить тысячи команд — у большинства из них сборка забирает latest-версию без явного закрепления.

Как работает атака

plain-crypto-js: вредоносная зависимость

Злоумышленник не патчил код самого Axios. Вместо этого он добавил в зависимости пакет plain-crypto-js. Схема в два шага:

  • plain-crypto-js@4.2.0 — «чистая» версия, опубликована заранее для создания истории публикаций

  • plain-crypto-js@4.2.1 — вредоносная версия с postinstall-хуком: при установке автоматически скачивала и запускала stage-2 RAT с C2-сервера sfrclak[.]com:8000

RAT — кросс-платформенный: отдельные payload для macOS, Windows и Linux. После установки соединения с C2 — полный удалённый доступ к машине.

Почему это прошло через большинство CI/CD без остановки

CI/CD-пайплайны собирают, тестируют и доставляют обновления без участия человека. Когда команда не закрепляет конкретную версию зависимости, а указывает последнюю доступную (^1.x.x), при каждой сборке npm резолвит актуальный latest. В окно между 30 и 31 марта — это была 1.14.1 с RAT внутри.

Большинство команд не имеют в CI/CD шага, который проверяет безопасность зависимостей до сборки. По данным OpenSSF Scorecard 2024, менее 20% открытых проектов используют закреплённые хеши зависимостей. У коммерческих проектов, которые тянут эти пакеты, картина не лучше.

Почему NPM Audit не остановил атаку

NPM Audit сравнивает установленные пакеты с базой CVE. На момент атаки ни Axios 1.14.1, ни plain-crypto-js 4.2.1 не числились в базах — они были свежеопубликованы. NPM Audit сканировал их и возвращал статус clean.

Логика инструмента здесь не ломается — она просто неприменима к этому классу атак. CVE-базы фиксируют известные уязвимости. Атака через компрометацию аккаунта публикует формально новый пакет, который ещё не успел попасть ни в какую базу.

Этот инцидент поймал инструмент другого класса: Elastic Security Labs обнаружила атаку через поведенческий мониторинг — отслеживание изменений метаданных пакетов (смена email, метод публикации, новая зависимость в релизе без истории изменений).

Зависимости — новый периметр безопасности

Что сломалось в старой парадигме?

Раньше ответственность делилась по ролям: тимлид или архитектор решал, какой модуль добавить; DevOps следил за процессом доставки; безопасники подключались позже с SAST/DAST-проверками; юристы — за лицензиями. Каждый проверял своё.

Инцидент с Axios показывает разрыв в этой схеме: никто из них не проверял, остался ли аккаунт мейнтейнера под контролем легитимного человека. Уровень доверия к подписанным пакетам оказался не абсолютным — он был привязан к конкретной учётной записи, которую можно угнать.

174 000 пакетов: почему масштаб такой

Axios входит в топ-5 самых скачиваемых пакетов npm. 174 000 пакетов прямо или транзитивно зависят от него. Механика та же, что в CMS-эпоху с WordPress и Joomla: одна уязвимость в ядре — ключ ко всем проектам на этой платформе.

Стандартный Node.js-проект содержит 40–60 прямых зависимостей. У каждой из них — свои зависимости, в среднем по 5–7 пакетов. Итого: 40 × 5 = 200+ пакетов, которые молча живут в вашем проекте, и за каждым — конкретный человек с учётной записью.

Транзитивные зависимости — отдельный класс: пакеты, нужные только на этапе сборки и не попадающие в production. Они тоже могут нести угрозу и при этом вообще не попадают в фокус code review.

Как AI меняет соотношение сил

AI ускоряет написание кода, помогает с troubleshooting и делает автоматическое code review. Те же возможности работают против защитников: нейросеть сканирует чужой код на уязвимости за минуты — задача, на которую опытный специалист раньше тратил часы.

Атрибуция этого инцидента — северокорейский threat actor (по данным Google Cloud Threat Intelligence). Это уже не скрипт-кидди с форума. Государственные группы используют AI для поиска точек входа в supply chain, автоматически сканируя тысячи пакетов на слабые аккаунты мейнтейнеров.

Количество уязвимостей в open source коде, которые ещё не выявлены и не задокументированы, исчисляется миллионами. По данным исследования Google Project Zero за 2023 год, медианное время от обнаружения уязвимости до публичного патча — 25 дней. AI сокращает время поиска на стороне атакующих быстрее, чем растут команды безопасности на стороне защитников.

Что остановило бы эту атаку

npm audit signatures

Команда проверяет криптографические подписи каждого пакета и подтверждает, что публикация прошла через официальный CI/CD-пайплайн с SLSA-провенансом — а не через прямой CLI-publish с изменённого аккаунта.

npm audit signatures

В случае Axios 1.14.1 эта проверка выявила бы аномалию немедленно: смена метода публикации с OIDC на прямой CLI — явный флаг. Именно этот сигнал поймала Elastic Security Labs в своём мониторинге.

Что нужно встроить в CI/CD

  • Закреплённые версии или хеши зависимостей — npm install --frozen-lockfile или использование package-lock.json с commitом в репозиторий

  • npm audit signatures — проверка подписей перед каждой сборкой

  • SAST на зависимости — статический анализ не только своего кода, но и устанавливаемых пакетов

  • Dependabot или аналоги — автоматические уведомления об уязвимостях в зависимостях с известными CVE

  • Поведенческий мониторинг пакетов — анализ metaданных релизов: смена email, смена метода публикации, новые зависимости без истории

Крупные компании уже внедряют эти практики в рамках DevSecOps. Малые проекты — пока нет. Именно они и составляют большую часть из 174 000 пострадавших пакетов.

Итог

За 3 часа 30–31 марта 2026 года один скомпрометированный аккаунт мейнтейнера превратил библиотеку с 100 млн загрузок в неделю в вектор доставки RAT на macOS, Windows и Linux. Атака остановилась не потому, что сработала защита большинства команд — а потому что Elastic Security Labs вела поведенческий мониторинг и быстро инициировала удаление пакетов из реестра.

Периметр сети, права доступа, свой код — всё это давно под контролем. Зависимости — чужой код, за которым стоит конкретный человек с учётной записью — оставались вне этого периметра. Инцидент с Axios закрыл этот слепой пятно для тех, кто его заметил.

Те, кто не заметил, узнают позже — когда что-то пойдёт не так.