Двенадцатого мая 2026 года команда Threat Research компании Socket обнаружила масштабную компрометацию цепочки поставок программного обеспечения. Вредоносные изменения были внесены в 84 пакета из пространства имён TanStack. Среди поражённых артефактов оказался @tanstack/react-router, который еженедельно загружают более 12 миллионов раз. Такая популярность делает инцидент особенно критичным для всей экосистемы npm.
Описание
Злоумышленники модифицировали легитимные версии пакетов, добавив в них файл router_init.js. Этот файл объёмом около 2,3 мегабайта содержит сильно обфусцированный код, который маскируется под обычный инициализационный модуль. На самом деле это полноценный червь, нацеленный на кражу учётных данных и дальнейшее распространение. Специалисты Socket отметили, что их ИИ-сканер выявлял подозрительные пакеты в течение шести минут после публикации.
Атака на TanStack стала возможной благодаря многоступенчатой эксплуатации механизмов GitHub Actions. Как показал разбор инцидента, злоумышленники использовали уязвимость, известную как "Pwn Request", связанную с событием pull_request_target. Они отравили кэш GitHub Actions, преодолев границу доверия между форком и оригинальным репозиторием. Ключевым этапом стало извлечение из памяти выполняющегося раннера OIDC-токена (токена для децентрализованной аутентификации без пароля). С его помощью злоумышленники смогли аутентифицироваться в реестре npm и опубликовать вредоносные версии пакетов. При этом, по заявлению команды TanStack, их собственные учётные данные npm не были скомпрометированы, а сам конвейер публикации остался нетронутым.
Анализ файла router_init.js показал сложную архитектуру вредоносной программы. Код использует двойное шифрование: стандартный обфускатор JavaScript-Obfuscator с вращением массивов строк и шестнадцатеричными идентификаторами, а поверх него - дополнительную функцию beautify(), которая декодирует base64-зашифрованные строки во время выполнения. Файл содержит механизм демонизации: при первом запуске он проверяет наличие переменной окружения __DAEMONIZED, и если её нет, создаёт откреплённый дочерний процесс, который работает в фоне, а родительский процесс завершается. Таким образом, установка пакета проходит незаметно.
Затем вредоносная программа приступает к сбору информации. Она проверяет, работает ли в среде GitHub Actions, после чего начинает красть секреты. Среди целей - переменные окружения GITHUB_TOKEN, AWS_ACCESS_KEY_ID, VAULT_TOKEN, а также внутренние конечные точки облачных провайдеров. Червь обращается к метаданным EC2 (169.254.169.254), к HashiCorp Vault, запущенному внутри Kubernetes, и к сервисному аккаунту Kubernetes. Извлечённые данные он передаёт через децентрализованную P2P-сеть Session, используя её протокол для шифрования и маршрутизации. Трафик при этом выглядит как обычный зашифрованный обмен сообщениями между пользователями Session.
Особую опасность представляет механизм самовоспроизведения. Червь не только крадёт токены, но и использует OIDC-федерацию GitHub Actions для публикации своих копий в реестре npm от имени скомпрометированного мейнтейнера. Кроме того, он заражает исходные репозитории жертв через GraphQL API GitHub, создавая коммиты с поддельным автором claude@users.noreply.github.com. Эти коммиты добавляют вредоносные файлы в каталоги .claude и .vscode, что обеспечивает закрепление на рабочих станциях разработчиков. Даже после удаления заражённого npm-пакета код продолжает выполняться при использовании Claude Code или открытии проекта в VS Code.
Кампания, получившая название Mini Shai-Hulud, не ограничилась пакетами TanStack. Специалисты Socket выявили аналогичные компрометации в других популярных проектах. Среди них - UiPath (более 30 пакетов), Mistral AI (версии пакетов @mistralai/mistralai 2.2.2 и выше), OpenSearch (версии 3.5.3-3.8.0), Guardrails AI (версия 0.10.1 на PyPI) и множество более мелких пакетов, таких как пакеты @squawk, @tallyui и другие. В случае с Guardrails AI вредоносный код выполнялся при импорте модуля, проверял, работает ли система под Linux, и скачивал удалённый артефакт с домена git-tanstack.com. На момент расследования этот домен отображал сообщение "We've been online over 2 hours now stealing creds" с подписью "With Love TeamPCP".
Последствия атаки огромны. Поскольку вредоносные пакеты имеют высокую посещаемость и транзитивные зависимости, любая сборка, включающая их, могла привести к утечке всех секретов CI/CD и облачной инфраструктуры. Команда TanStack быстро отреагировала: они пометили затронутые версии как устаревшие, обратились в службу безопасности npm для удаления вредоносных архивов, очистили кэш GitHub Actions и внесли изменения в конвейеры публикации, включая добавление проверок владельца репозитория и фиксацию ссылок на сторонние действия.
Специалистам по информационной безопасности рекомендуется немедленно проверить контрольные суммы файлов router_init.js (SHA-256 ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c) во всех зависимых деревьях. Также необходимо ротировать все секреты, которые могли быть скомпрометированы, включая токены npm, GitHub PAT, OIDC-доверия, учётные данные AWS, ключи Vault и токены сервисных аккаунтов Kubernetes. Следует отозвать OIDC-гранты для всех пакетов, опубликованных из затронутых репозиториев, и пересоздать их только после проверки конвейера. Дополнительно стоит провести аудит каталогов .claude и .vscode в домашних директориях разработчиков и корнях проектов, а также проверить историю коммитов на наличие автора claude[@]users.noreply.github.com. На периметре сети рекомендуется заблокировать исходящий трафик к домену filev2.getsession[.]org, если он не используется.
Этот инцидент показывает, насколько уязвимой стала цепочка поставок в мире открытого кода. Злоумышленники не просто воруют учётные данные - они создают самовоспроизводящиеся черви, способные автономно распространяться через механизмы доверенной публикации. Использование децентрализованных сетей для эксфильтрации данных затрудняет обнаружение и блокировку каналов управления. Разработчикам и администраторам необходимо пересмотреть подходы к безопасности пайплайнов CI/CD, минимизировать объём полномочий токенов и внедрять проверки целостности пакетов на всех этапах жизненного цикла разработки.
Индикаторы компрометации
Domain Port Combinations
- vault.svc.cluster.local:8200
URLs
- http://169.254.169.254/latest/api/token
- http://169.254.170.2
- http://filev2.getsession.org/file/
- https://api.github.com/repos/
- https://registry.npmjs.org/-/npm/v1/tokens
MD5
- 833fd59ebe66a4449982c6d18db656b4
- b82e54923f7e440664d2d75bd31588ca
SHA1
- 12ed9a3c1f73617aefdb740480695c04405d7b4b
- e7d582b98ca80690883175470e96f703ef6dc497
SHA256
- 2ec78d556d696e208927cc503d48e4b5eb56b31abc2870c2ed2e98d6be27fc96
- ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c