Вечером 27 мая 2026 года неизвестный злоумышленник, контролирующий два аккаунта в реестре npm, единовременно загрузил 164 вредоносных пакета. Каждый из них имитировал внутренние модули облачной платформы и финансовой организации. Установка любого такого пакета приводила к немедленному сбору и отправке всех переменных окружения разработчика или сборочного конвейера на сервер злоумышленника. Под угрозой оказались все команды, чьи зависимости разрешаются через публичный реестр npm без блокировки скоупов.
Описание
Оба аккаунта действовали с интервалом всего в 22 минуты. Первый, mr.4nd3r50n, начал публикацию в 21:15 UTC и выложил 139 пакетов в двух скоупах. Второй, pik-libs, стартовал в 21:37 UTC и добавил ещё 25 пакетов ещё в трёх скоупах. Идентичный код полезной нагрузки, одинаковые жёстко зашитые секреты и единый адрес центра управления - https://oob.moika.tech - не оставляют сомнений: оба аккаунта управляются одним человеком. Версия всех пакетов указана как 99.99.99, что сразу привлекает внимание, но социальная инженерия в описаниях маскирует угрозу.
Каждый активный пакет содержит сценарий postinstall (запуск после установки). После установки он ждёт три секунды, чтобы обойти быстрые песочницы, определяет операционную систему (macOS, Windows или Linux) и загружает вторую стадию с того же сервера. Вторая стадия сохраняется во временную папку как файл ._cloudplatform-single-spa_init.js и запускается как отдельный процесс, который продолжает работу даже после завершения npm install. Затем происходит сбор process.env - всех переменных окружения, включая API-ключи, токены, пароли к базам данных, секреты облачных провайдеров. Эти данные уходят на сервер вместе с именем хоста, именем пользователя, архитектурой и текущей директорией. Если загрузка второй стадии не удаётся, данные уходят без неё.
Особую опасность атаке придаёт качество проработки. Имена пакетов не являются случайными: @cloudplatform-single-spa/certificate-manager, @cloudplatform-single-spa/vpn, @cloudplatform-single-spa/ml-inference, @car-loans/mobile-car-loans-application, @fb-deposit/form-deposit-auth. Они зеркалируют настоящие внутренние названия сервисов. Описание каждого пакета гласит: "Internal configuration loader with env, vault and remote config support". В файле README подделывается типичная корпоративная документация: указаны вымышленные URL документации и трекера задач (docs.car-loans.io, jira.car-loans.io), приведён комментарий про настройку приватного реестра в .npmrc. Самый хитрый приём - раздел "Telemetry". Там сказано, что пакет при установке отправляет анонимную телеметрию на домен telemetry.cloudplatform-single-spa.io для мониторинга совместимости. Приводится переменная для отключения этой "телеметрии". Разработчик, заметивший исходящее сетевое соединение, может подумать, что это разрешённая внутренняя статистика, а не похищение данных. На деле данные уходят на сервер oob.moika.tech.
Исследователи из компании SafeDep обнаружили обе публикации в режиме реального времени. Они отметили, что два пакета из скоупа mr.4nd3r50n - @cloudplatform-single-spa/logaas и @mlspace/model-registry - не содержат активной полезной нагрузки. В их описании указано "BugBounty testing by mr4nd3r50n". Скорее всего, злоумышленник сначала проверил, что внутренние имена пакетов разрешаются в публичном реестре, и только после этого развернул полномасштабную кражу. Оставшиеся 162 пакета работали на полную мощность.
По масштабу эта кампания превосходит многие предыдущие атаки на цепочку поставок. Для сравнения, известная кампания sl4x0 длилась девять месяцев и включала 92 пакета против двадцати организаций. Здесь же 164 пакета появились менее чем за полчаса. Кроме того, большинство разведывательных проб обычно отправляют только DNS-запросы с именем хоста и именем пользователя - достаточно для подтверждения попадания, но не для нанесения ущерба. Этот же злоумышленник сразу передаёт сырой process.env. Если пакет установлен на сборочном конвейере, где активны облачные учётные данные, это равносильно полной компрометации этих учётных записей.
Что делать командам, которые могут быть затронуты? В первую очередь необходимо заблокировать все пять скоупов (@cloudplatform-single-spa, @mlspace, @car-loans, @fb-deposit, @debit-ib) в приватный реестр. Без такой блокировки npm будет разрешать зависимости из публичного реестра, если приватная версия недоступна. Далее нужно немедленно сменить все секреты, которые могли находиться в переменных окружения на системах, где устанавливались пакеты версии 99.99.99. Стоит проверить списки процессов и временные папки на наличие файла ._cloudplatform-single-spa_init.js, а также проанализировать сетевые логи на соединения с доменом oob.moika.tech. Наконец, рекомендуется прогнать lock-файлы через автоматические сканеры - они помогут выявить подозрительные пакеты до следующего цикла установки.
Этот инцидент в очередной раз напоминает, что цепочки поставок программного обеспечения остаются уязвимым звеном. Даже один непроверенный пакет, установленный из публичного реестра, может привести к утечке всех ключей доступа. Компаниям стоит не только строго контролировать источники зависимостей, но и внедрять автоматическую проверку пакетов на вредоносное поведение. Пока же ответственным за безопасность придётся оперативно реагировать на последствия атаки, которая длилась всего 25 минут, но может обернуться многомесячными последствиями.
Индикаторы компрометации
URLs
- https://oob.moika.tech/payload/{mac|win|linux}.j
- https://oob.moika.tech/report
Packages
- @car-loans/applicaion-aff
- @car-loans/application-aff
- @car-loans/close-flow-module
- @car-loans/deal
- @car-loans/deal-aff
- @car-loans/desktop-car-loans-application
- @car-loans/feature-toggles-module
- @car-loans/general-analytics
- @car-loans/general-feature-toggles
- @car-loans/gus
- @car-loans/mobile-car-loans-application
- @car-loans/online-scoring-aff
- @car-loans/online-sign-aff
- @car-loans/referrer-module
- @car-loans/restore
- @car-loans/safe-storage-module
- @car-loans/save
- @car-loans/show-car-year-module
- @car-loans/wait-task-props
- @cloudplatform-single-spa/administration
- @cloudplatform-single-spa/advanced
- @cloudplatform-single-spa/agreements
- @cloudplatform-single-spa/aifactory-notebooks
- @cloudplatform-single-spa/airflow
- @cloudplatform-single-spa/anti-ddos
- @cloudplatform-single-spa/arenadata-db
- @cloudplatform-single-spa/audit-log
- @cloudplatform-single-spa/bare-metal-servers
- @cloudplatform-single-spa/base-static-page
- @cloudplatform-single-spa/billing
- @cloudplatform-single-spa/business-solutions
- @cloudplatform-single-spa/certificate-manager
- @cloudplatform-single-spa/clickhouse
- @cloudplatform-single-spa/cloud-dns
- @cloudplatform-single-spa/cloudia
- @cloudplatform-single-spa/cnapp-ui
- @cloudplatform-single-spa/container-registry
- @cloudplatform-single-spa/corax
- @cloudplatform-single-spa/cp-api-gw
- @cloudplatform-single-spa/datagrid
- @cloudplatform-single-spa/dataplatform
- @cloudplatform-single-spa/dataplatform-bi
- @cloudplatform-single-spa/dataplatform-cloudberry
- @cloudplatform-single-spa/dataplatform-clusters
- @cloudplatform-single-spa/dataplatform-connections
- @cloudplatform-single-spa/dataplatform-flink
- @cloudplatform-single-spa/dataplatform-metastore
- @cloudplatform-single-spa/dataplatform-nessie
- @cloudplatform-single-spa/dataplatform-spark
- @cloudplatform-single-spa/dataplatform-trino
- @cloudplatform-single-spa/disks
- @cloudplatform-single-spa/dns
- @cloudplatform-single-spa/document-db
- @cloudplatform-single-spa/edge-manager
- @cloudplatform-single-spa/employees
- @cloudplatform-single-spa/enterprise
- @cloudplatform-single-spa/event-bus
- @cloudplatform-single-spa/evocs
- @cloudplatform-single-spa/evolution
- @cloudplatform-single-spa/floating-ips
- @cloudplatform-single-spa/iam
- @cloudplatform-single-spa/installations
- @cloudplatform-single-spa/key-manager
- @cloudplatform-single-spa/logaas
- @cloudplatform-single-spa/magic-bridge
- @cloudplatform-single-spa/magic-router
- @cloudplatform-single-spa/managed-identities
- @cloudplatform-single-spa/marketplace-apps
- @cloudplatform-single-spa/marketplace-gigachat
- @cloudplatform-single-spa/marketplace-main
- @cloudplatform-single-spa/ml-ai-agents-agent
- @cloudplatform-single-spa/ml-ai-agents-agent-system
- @cloudplatform-single-spa/ml-ai-agents-evo-claw
- @cloudplatform-single-spa/ml-ai-agents-ide
- @cloudplatform-single-spa/ml-ai-agents-marketplace
- @cloudplatform-single-spa/ml-ai-agents-mcp-server
- @cloudplatform-single-spa/ml-ai-agents-system-prompt
- @cloudplatform-single-spa/ml-ai-agents-trigger
- @cloudplatform-single-spa/ml-finetuning
- @cloudplatform-single-spa/ml-foundation-models
- @cloudplatform-single-spa/ml-inference
- @cloudplatform-single-spa/ml-inference-comfy-run
- @cloudplatform-single-spa/ml-inference-docker-run
- @cloudplatform-single-spa/ml-inference-marketplace
- @cloudplatform-single-spa/ml-inference-model-run
- @cloudplatform-single-spa/ml-inference-router
- @cloudplatform-single-spa/ml-rag
- @cloudplatform-single-spa/mlspace-access-request
- @cloudplatform-single-spa/monaas-ui
- @cloudplatform-single-spa/monitoring
- @cloudplatform-single-spa/notification-gateway
- @cloudplatform-single-spa/observability
- @cloudplatform-single-spa/onboarding
- @cloudplatform-single-spa/opensearch
- @cloudplatform-single-spa/paas-kafka
- @cloudplatform-single-spa/paas-redis
- @cloudplatform-single-spa/pangolin
- @cloudplatform-single-spa/postgre
- @cloudplatform-single-spa/profile
- @cloudplatform-single-spa/rabbitmq
- @cloudplatform-single-spa/redirect
- @cloudplatform-single-spa/resource-manager
- @cloudplatform-single-spa/search
- @cloudplatform-single-spa/secret-manager
- @cloudplatform-single-spa/security-groups
- @cloudplatform-single-spa/self-service
- @cloudplatform-single-spa/serverless-containers
- @cloudplatform-single-spa/smk
- @cloudplatform-single-spa/solutions
- @cloudplatform-single-spa/ssh-keys
- @cloudplatform-single-spa/static-page
- @cloudplatform-single-spa/subnets
- @cloudplatform-single-spa/support
- @cloudplatform-single-spa/svp-agent-backup
- @cloudplatform-single-spa/svp-anti-affinity
- @cloudplatform-single-spa/svp-baas
- @cloudplatform-single-spa/svp-bare-metal-servers
- @cloudplatform-single-spa/svp-draas
- @cloudplatform-single-spa/svp-gateways
- @cloudplatform-single-spa/svp-gitaas
- @cloudplatform-single-spa/svp-images
- @cloudplatform-single-spa/svp-interfaces
- @cloudplatform-single-spa/svp-lbaas
- @cloudplatform-single-spa/svp-managed-kubernetes
- @cloudplatform-single-spa/svp-pipeline
- @cloudplatform-single-spa/svp-s3-storage
- @cloudplatform-single-spa/svp-tags
- @cloudplatform-single-spa/svp-tasks
- @cloudplatform-single-spa/svp-vdi
- @cloudplatform-single-spa/svp-vm-migration
- @cloudplatform-single-spa/timescale-db
- @cloudplatform-single-spa/vcenter-manager
- @cloudplatform-single-spa/vcenter-virtual-machines
- @cloudplatform-single-spa/vdi
- @cloudplatform-single-spa/virtual-ip
- @cloudplatform-single-spa/virtual-machines
- @cloudplatform-single-spa/vmmanager
- @cloudplatform-single-spa/vmware-draas
- @cloudplatform-single-spa/vpc
- @cloudplatform-single-spa/vpc-endpoint
- @cloudplatform-single-spa/vpn
- @debit-ib/desktop-debit-ib-additional-card-form
- @debit-ib/mobile-debit-ib-additional-card-form
- @fb-deposit/form-deposit
- @fb-deposit/form-deposit-auth
- @fb-deposit/form-deposit-calc
- @fb-deposit/form-savings-account
- @mlspace/allocations
- @mlspace/connectors
- @mlspace/docker-registry
- @mlspace/dtransfer
- @mlspace/dtransfer-history
- @mlspace/env-gitlab
- @mlspace/env-jobs
- @mlspace/env-jupyter-server
- @mlspace/experiments
- @mlspace/experiments-monitoring
- @mlspace/file-manager
- @mlspace/inference-build
- @mlspace/inference-deploy
- @mlspace/model-monitoring
- @mlspace/model-registry
- @mlspace/profile
- @mlspace/shared-storage