Взлом injective npm зафиксирован в реестре NPM. Скомпрометирован официальный пакет @injectivelabs/sdk-ts версии 1.20.21. Один аккаунт разработчика. Доступ к seed-фразам потенциально десятков тысяч пользователей.
Не фишинг. Не поддельный сайт. Обновление пакета, которому доверяли все, кто строит на Injective. Согласно данным, вредоносная версия вышла под официальным именем, с легитимной историей коммитов позади.
Как начался взлом injective npm
Злоумышленники получили доступ к учётной записи разработчика Injective в реестре NPM. Этого хватило. Стандартные проверки безопасности репозитория были обойдены: пакет опубликовали под настоящим именем, и система приняла его как легитимное обновление.
@injectivelabs/sdk-ts это не вспомогательная утилита. Это базовый инструментарий для создания кошельков, DEX-платформ, DeFi-приложений и платёжных сервисов в сети Injective. Около 50 000 загрузок в неделю. Разработчики подключают его автоматически при инициализации проекта, не заглядывая внутрь.
Вот что интересно. Именно автоматическое доверие превращает единичную компрометацию в системную угрозу.
Схема каскадного распространения бэкдора: 1 скомпрометированный аккаунт → 1 заражённый пакет → 17 св
Каскад: 17 пакетов, потом ещё 87
Вредоносный код не остановился на одном пакете. Injective использует архитектуру взаимосвязанных модулей. Компрометация базового SDK автоматически распространилась ещё через 17 официальных пакетов экосистемы.
Дальше сработала механика открытых зависимостей. Под угрозой оказались как минимум 87 сторонних пакетов, которые импортировали заражённые библиотеки. Совокупное число загрузок всех уязвимых зависимостей превысило 112 000.
Это не просто цифра. За каждой загрузкой стоит проект, который мог собрать релизную версию с активным бэкдором внутри. CI/CD-конвейеры, docker-образы, роботы обновления зависимостей подхватывают новую версию без участия человека и молча деплоят её в продакшн.
Скрипт, который притворялся статистикой
Вредоносный код был замаскирован под модуль сбора технической статистики. Автоматические сканеры уязвимостей его не поймали. В состоянии покоя он не делал ничего подозрительного.
Активация происходила только в один момент: при создании нового кошелька или его подключении к DApp. Тогда скрипт перехватывал seed-фразы и приватные ключи в открытом виде и отправлял их на удалённый сервер.
Пассивный аудит кода не покажет угрозу, если не воспроизвести именно это условие. Большинство проверок его и не воспроизводят. И здесь принципиальный момент: аудиты смарт-контрактов проверяют логику контракта. Они не проверяют, что происходит в JavaScript-среде, которая генерирует ключи до того, как транзакция вообще дошла до блокчейна. О похожих механиках кражи через среду исполнения писали в разборе атак на смарт-контракты и MEV-боты.
Кому это угрожало реально
Рядовые пользователи Injective не были прямой целью. Цель это разработчики, которые подключили заражённый SDK к своим продуктам. Через них угроза транслировалась дальше: в торговые боты, в интерфейсы DEX, в мобильные кошельки, в интеграции бирж.
Пользователь, создавший кошелёк через заражённое приложение, передал свою seed-фразу злоумышленникам, не зная об этом. Никакой аномалии в интерфейсе. Никакого предупреждения. Всё выглядело штатно.
Разработчики, которые скачали версию 1.20.21 и не провели принудительный аудит зависимостей, до сих пор могут не знать, что их продукт заражён. Особенно если бэкдор попал в кэшированный docker-слой или уже собранный бинарник. Проверить и отозвать активные аппрувы DeFi-контрактов в такой ситуации это первый практический шаг, подробная инструкция есть в разборе как отозвать аппрувы после предупреждения OpenZeppelin.
Supply chain атаки: почему именно NPM
Реестр NPM содержит более 2 миллионов пакетов. Большинство поддерживаются одним-двумя разработчиками, без корпоративных процессов безопасности вокруг учётных данных. Аккаунт без аппаратного 2FA, скомпрометированный через фишинг или утечку базы паролей, открывает прямой путь к публикации вредоносного обновления.
Атака на цепочку поставок через открытые библиотеки становится в Web3 таким же распространённым вектором, как фишинговые сайты. Разница вот в чём: фишинг требует от жертвы ошибки. Supply chain атака не требует ничего. Пользователь просто обновил зависимости.
| Вектор атаки | Фишинг | Supply chain (NPM) |
|---|---|---|
| Действие жертвы | Клик по ссылке, ввод фразы | Обновление зависимостей |
| Видимость угрозы | Подозрительный домен | Легитимное имя пакета |
| Точка входа | Пользователь | Разработчик |
| Масштаб | Отдельные жертвы | Каскад по зависимостям |
По существу. Крах аудита Accountable показал ту же логику: доверие к формальным проверкам не заменяет независимую верификацию. Формальный аудит смотрит на код в статике. Поведенческий триггер в этот момент спит.
Что делать разработчику при взломе injective npm
- Проверить lock-файл на наличие версии 1.20.21 пакета @injectivelabs/sdk-ts или любого из 17 связанных пакетов Injective.
- Если заражённая версия попала в сборку, считать все ключи и seed-фразы, сгенерированные через эту сборку, скомпрометированными. Немедленный перевод средств на новые адреса.
- Включить аппаратный 2FA на всех аккаунтах NPM в организации. Не SMS. Аппаратный ключ.
- Настроить мониторинг изменений хэшей критических зависимостей в CI/CD.
Одного скомпрометированного аккаунта разработчика в экосистеме с 50 000 загрузок в неделю достаточно, чтобы угроза стала системной. CI/CD-системы, которые автоматически тянут зависимости, могли размножить заражённый код в производственные сборки без единого ручного действия.
Материал носит информационный характер и не является финансовой или технической рекомендацией. Криптоактивы связаны с высоким риском полной потери средств. Проверяйте зависимости и учётные данные самостоятельно, перед любыми действиями с ключами консультируйтесь с профильными специалистами по безопасности.
Как понять, что мой проект использовал заражённую версию?
Проверьте файл package-lock.json или yarn.lock на наличие версии 1.20.21 пакета @injectivelabs/sdk-ts. Если она присутствует, нужен полный аудит: все ключи, сгенерированные через этот код, следует считать скомпрометированными.
Помогает ли откат на предыдущую версию SDK?
Откат на чистую версию убирает вредоносный код из зависимостей, но не отменяет уже случившуюся утечку. Если бэкдор успел отработать и сгенерированные ключи ушли на сервер злоумышленника, эти адреса остаются скомпрометированными навсегда. Откат защищает будущие сборки, а не уже созданные кошельки. Средства с затронутых адресов нужно переводить независимо от обновления пакета.
Почему автоматические сканеры не нашли вредоносный код сразу?
Скрипт имитировал модуль сбора технической статистики и оставался пассивным до конкретного триггера. Статические анализаторы проверяют паттерны известных атак, а не поведенческую логику в условии. Для обнаружения нужен динамический анализ с воспроизведением сценария создания кошелька.
ФИНАЛ: один взломанный аккаунт обошёл всю систему доверия NPM. Пока зависимости обновляются автоматически, каждая релизная сборка это лотерея с чужими ключами.