Новая атака на цепочку поставок ударила по восьми пакетам в Packagist. Злоумышленники спрятали вредоносный скрипт не в Composer-метаданных, а в package.json, чтобы запускать Linux-бинарник во время установки и сборки проекта.

История инцидента

По данным Socket, заражённые версии пакетов уже убрали из Packagist. Речь идёт о проектах, где PHP-код соседствует с JavaScript-инструментами сборки, а значит, у атакующих появился ещё один путь к запуску кода на машине разработчика или в CI/CD-пайплайне.

Схема выглядела незаметно. Скрипт в package.json пытался скачать бинарник с URL на GitHub Releases, сохранить его в /tmp/.sshd, выдать ему права на запуск через chmod и тихо поднять процесс в фоне.

Атака затронула пакеты вроде moritz-sauer-13/silverstripe-cms-theme, devdojo/wave, devdojo/genesis и ещё несколько. Исследователи также нашли следы того же payload в сотнях файлов на GitHub, а в ряде случаев — прямо в workflow-файлах.

Что пошло не так в защите

Главная проблема — проверка шла не там, где спрятали угрозу. Команды, которые смотрят только на Composer-зависимости, могли пропустить package.json и его lifecycle-хуки. Именно на этом и сыграли атакующие: вредонос оказался в «чужом» для PHP-проекта месте.

Это не первый случай, когда атакующие смешивают экосистемы. Ранее похожую логику уже показывала атака на Laravel-Lang: как подменили теги пакетов и что делать, а затем — разбор, где из пакетов вытаскивали секреты и токены: атака на Laravel Lang показала, как воруют секреты через пакеты.

В этой истории опаснее всего не сам бинарник, а момент запуска. Он срабатывает во время установки или в GitHub Actions jobs, то есть там, где разработчики обычно доверяют окружению и не ждут подвоха. По словам Socket, вредонос ещё и пытался скрыть следы: отключал проверку TLS, подавлял ошибки и запускал процесс в фоне.

Уроки для читателя

Этот кейс хорошо показывает, почему цепочку поставок нельзя проверять по одному индикатору. Если в проекте есть и PHP, и JavaScript, нужно смотреть оба слоя метаданных, а не только тот, который кажется основным.

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

Сходный подход виден и в других инцидентах на рынке. Например, в разборе npm усилил контроль публикаций и установок для защиты цепочки поставок хорошо видно, как много значит контроль над жизненным циклом пакета, а не только его названием и версией.

Практические выводы и чек-лист

Разработчикам и ИБ-командам стоит пересмотреть базовые проверки в репозиториях и CI.

  • Проверяйте не только composer.json, но и package.json, yarn.lock, package-lock.json и workflow-файлы.
  • Ищите посторонние postinstall-скрипты и любые команды, которые скачивают исполняемые файлы из интернета.
  • Запускайте установку зависимостей в изолированной среде, а не на рабочей машине с доступом к ключам и токенам.
  • Ограничьте права CI-сборок и уберите лишние секреты из окружения.
  • Сверяйте хеши и источники бинарников, которые появляются во время сборки.
  • Настройте ручную проверку свежих пакетов перед обновлением в продакшене.
  • Для работы из чужой или публичной сети используйте отдельный слой защиты для трафика, чтобы не светить служебные данные и сеансы входа.

Если в проекте много внешних зависимостей, полезно держать под рукой и антифишинговую базу: злоумышленники всё чаще начинают не с письма, а с пакета, который выглядит как обычная библиотека.

Поделиться: