Перейти к содержанию
Innovialabs

Атаки на цепочку поставок ПО и как от них защититься

Продвинутое4 мин

Коротко

Атака на цепочку поставок бьёт не по вашему коду, а по тому, из чего он собирается, — пакетам, инструментам и CI; защита строится на фиксации версий, запрете install-скриптов, SBOM, проверке подписей и минимальных правах в CI.

Коротко

Атака на цепочку поставок (supply chain attack) — это когда злоумышленник не взламывает ваше приложение напрямую, а подменяет то, из чего оно собирается: npm- или PyPI-пакет, GitHub Action, Docker-образ, инструмент сборки. Вредоносный код попадает в проект через обычный npm install и выполняется с правами разработчика или CI.

Основа защиты:

  1. Фиксировать точные версии и источники зависимостей.
  2. Не запускать чужие скрипты установки без необходимости.
  3. Знать состав сборки — SBOM.
  4. Проверять подписи и происхождение артефактов.
  5. Ограничить права CI, чтобы взлом одного шага не давал доступа ко всему.

Как атакуют

Тайпсквоттинг. Пакет с именем, похожим на популярный: опечатка, лишний дефис, другой порядок слов. Достаточно ошибиться одной буквой в npm install.

Dependency confusion. Если у компании есть внутренний пакет, например billing-utils, атакующий публикует пакет с тем же именем в публичный реестр с более высокой версией. Неправильно настроенный менеджер пакетов выберет публичный.

Взломанный мейнтейнер. Злоумышленник получает доступ к аккаунту автора популярной библиотеки или становится со-мейнтейнером, постепенно заслужив доверие. Известные примеры — event-stream в npm, куда новый мейнтейнер добавил зависимость с вредоносным кодом, и бэкдор в xz-utils, обнаруженный в 2024 году.

Вредоносные install-скрипты. Поля preinstall и postinstall в package.json выполняются автоматически при установке. Скрипт может прочитать .env, SSH-ключи, токены облака и отправить их наружу — ещё до того, как вы запустили приложение.

Подмена в CI. Сторонний GitHub Action, подключённый по тегу вроде @v3, можно изменить, перенаправив тег на другой коммит. Все пайплайны, которые используют этот тег, выполнят новый код с доступом к секретам.

Фиксация версий и источников

  • Коммитьте lock-файл и устанавливайте через npm ci — он не меняет версии.
  • Используйте scoped-пакеты для внутренних библиотек и явно привязывайте scope к своему реестру:
# .npmrc
@company:registry=https://npm.company.internal/
  • Не обновляйтесь на версию, вышедшую час назад: вредоносные релизы часто обнаруживают и удаляют в первые дни. В Renovate для этого есть настройка minimumReleaseAge.
  • В CI подключайте Actions по полному SHA коммита, а не по тегу, и обновляйте их через Dependabot или Renovate.

Install-скрипты

Большинству пакетов скрипты установки не нужны. Отключите их по умолчанию и разрешайте точечно тем, кому они действительно требуются (например, пакетам с нативной сборкой):

npm ci --ignore-scripts

Некоторые менеджеры пакетов позволяют вести явный список пакетов, которым разрешено выполнять скрипты, — пользуйтесь этим.

SBOM

SBOM (Software Bill of Materials) — полный список компонентов сборки с версиями. Он отвечает на вопрос «затронуты ли мы», когда выходит новость о скомпрометированном пакете: вместо ручного поиска — запрос по SBOM всех сервисов.

Стандартные форматы — CycloneDX и SPDX. Сгенерировать SBOM можно, например, так:

npm sbom --sbom-format cyclonedx > sbom.json   # в новых версиях npm
syft dir:. -o cyclonedx-json > sbom.json        # для любого проекта или образа

Генерируйте SBOM в CI на каждую сборку и храните рядом с артефактом.

Проверка подписей

  • npm audit signatures проверяет подписи пакетов из реестра и provenance-аттестации — подтверждение того, из какого репозитория и пайплайна собран пакет.
  • Публикуя свои пакеты, используйте npm publish --provenance из CI.
  • Для контейнеров используйте Sigstore cosign: подписывайте образы при сборке и проверяйте подпись перед деплоем.
cosign verify \
  --certificate-identity-regexp "https://github.com/org/app/" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/org/app:1.4.0

Защита CI

МераЧто даёт
Минимальные permissions для токена CI (contents: read по умолчанию)Скомпрометированный шаг не сможет писать в репозиторий
Секреты только в нужных job’ах и environmentsУтечка ограничена одним этапом
Осторожность с pull_request_target и кодом из форковЧужой код не получает доступ к секретам
Эфемерные раннерыВредонос не остаётся между сборками
Защищённые ветки и обязательное ревьюНельзя тихо изменить пайплайн
OIDC вместо долгоживущих облачных ключейНечего украсть надолго

Для систематической оценки зрелости полезны фреймворк SLSA и инструмент OpenSSF Scorecard.

Частые вопросы

Нет. npm audit находит известные уязвимости в уже опубликованных отчётах, а вредоносный пакет может быть свежим и ещё нигде не отмеченным. Нужны и фиксация версий, и отключение install-скриптов, и ограничения в CI.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.