Ваш код больше не ваш: как атакуют цепочку поставок ПО

Ваш код больше не ваш: как атакуют цепочку поставок ПО

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

Тема неприятная, но управляемая. Ниже — живое объяснение, где именно ломают доверие, как выглядят популярные векторы, почему «просто обновляться» уже недостаточно и какие технические и организационные практики действительно снижают риск.

Что такое атака на цепочку поставок и почему это больно всем

Цепочка поставок ПО — это весь маршрут от исходников и инструментов разработчика до финального обновления у клиента: редакторы кода, зависимости, системы контроля версий, конвейеры сборки, тестовые среды, артефакты, репозитории пакетов, контейнерные образы, механизмы доставки. Атака на эту цепочку — вмешательство на одном из этапов, после которого «заражённый» результат распространяется дальше как будто всё в порядке. Больно всем по одной причине: вы получаете проблему из доверенного источника. Срабатывает автоматизация, подписи выглядят честно, а обновление уже внутри.

Классы атак: где подменяют и что именно

Зависимости и экосистемы пакетов

Самый «классический» маршрут. Вредоносный код попадает в библиотеку, откуда скатывается в ваши сервисы. Есть несколько типичных сценариев. Имитация опечаток в названиях пакетов: создаётся пакет с названием, отличающимся одной буквой, и кто-то из команды случайно тянет именно его. Подмена внутренней зависимости публичным пакетом: если внутреннее имя не закреплено, менеджер пакетов может предпочесть найденный «снаружи» артефакт. Компрометация аккаунта сопровождающего библиотеку: злоумышленник получает доступ к публикации и выпускает обновление «с сюрпризом». И ещё вариант — тянете бинарный артефакт «как есть», а его сборка происходила неизвестно где и кем.

Компрометация исходников и репозиториев

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

Взлом конвейера сборки и инфраструктуры CI/CD

Билд-агенты, самописные плагины, кэш артефактов, секреты в переменных окружения — всё это лакомые цели. Если удаётся выполнить код на этапе сборки, вредонос можно встроить до подписи. Встречается подмена выходного артефакта после тестов, но до выкладки в хранилище. Отдельная боль — саморазмещённые раннеры и сборочные узлы, у которых слишком широкие права в сети и к секретам.

Компрометация канала обновлений и подписи кода

Даже идеальная сборка бесполезна, если канал доставки слабый. ДНС/сертификат на домене обновлений, доступ к аккаунту поставщика, подмена метаданных и зеркал — всё это позволяет подсунуть «правильному» клиенту «неправильный» пакет. Если атакующий завладел сертификатом подписи кода или сумел заставить систему доверять его подписи, вредонос пройдёт как легитимный релиз.

Контейнерные образы и базовые слои

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

Сторонние сервисы и поставщики как «задняя дверь»

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

Почему это срабатывает: три системных изъяна

Слепая вера в «последнюю версию». Если «обновиться» у вас равно «автоматически принять всё, что пришло», однажды вы примете то, чего не хотели. Избыточные права у конвейеров. Билд, тесты, выкладка и админские действия часто живут под одной и той же учёткой и видят все секреты — достаточно один этап взломать, чтобы забрать всё. Неясные границы ответственности. Кто отвечает за проверку зависимости? За подпись релиза? За целостность образа? Если ответа нет, ответ «никто».

Как защититься: технические меры, которые дают эффект

Политика зависимостей, а не «тянем всё подряд»

Закрепляйте версии, избегайте «плавающих» требований. Новые минорные и особенно мажорные версии пропускайте через карантин: сначала статический анализ и тесты, потом — постепенное включение через канареечные развертывания. Откажитесь от прямых сетевых запросов к публичным регистраторам в рабочих конвейерах; используйте внутренний прокси-репозиторий с кешем и «белым списком» источников. Вводите запрет на автоматическую подстановку пакетов извне для внутренних имён — это минимизирует подмену внутренней зависимости публичным пакетом. При выборе новых библиотек смотрите не только на звёздочки, но и на «здоровье» проекта: активность коммитов, число сопровождающих, наличие процесса ревью и релизных ключей.

Подписи на всём пути: от коммита до артефакта

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

Изоляция и «скромность» конвейеров сборки

Разделяйте этапы: сборка, тесты, выпуск, выкладка — разные контуры, разные учётные записи, разные наборы секретов. Всё, что может работать на временных ключах, должно работать на временных ключах; долгоживущие токены и мастер-ключи — под замком и с ротацией. Билд-агенты запускайте в одноразовых окружениях: после сборки узел утилизируется вместе со всем кешем. Самописные плагины и раннеры — только с ревью и подписью. Доступ конвейера в интернет — минимальный и предсказуемый; лучше «он тянет из внутреннего зеркала», чем «гуляет по миру».

Защита репозиториев и правил внесения изменений

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

Контейнеры: закрепляйте базовые образы и проверяйте слои

Не «latest», а конкретные дайджесты. Прежде чем обновлять базовый образ, прогоните его через сканеры уязвимостей и лицензий, соберите список компонентов (перечень SBOM) и проверьте, не добавилось ли чего-то сомнительного. Храните у себя проверенные реплики базовых образов; выкачивайте из внешнего мира только через карантин и проверку подписи. В пайплайне добавьте шаг перекомпиляции критичных бинарников из исходников — меньше доверяйте готовым сборкам.

Разработчики тоже «звенящее звено»

Рабочие станции разработчиков — любимая цель. Если злоумышленник закрепится там, дорога к репозиторию и секретам открыта. Минимизируйте локальные секреты, используйте подтверждение владения ключом при доступе к репозиториям, вводите обязательную многофакторную аутентификацию, отделяйте «личную» и «рабочую» среду. Не позволяйте разворачивать произвольные агенты удалённого доступа и экспериментальные инструменты без отдельного согласования. И, да, банально, но правда: меньше прав — меньше бед.

Наблюдаемость и политика «не доверяй, пока не проверил»

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

Организационные меры: не всё решается в YAML-файлах

Управление поставщиками и третьими сторонами

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

Процессы выпуска и приёмки

Релиз — это не «кто-то нажал кнопку». Это последовательность проверок, где каждая оставляет след: что именно вошло, кто утверждал, какие тесты прошли, какие подписи были. На приёмке у клиента — своя дисциплина: проверка подписи, сверка метаданных, запуск сначала на небольшом сегменте (канареечная схема), мониторинг аномалий в первые часы. Чем больше автоматизировано, тем меньше «человеческого фактора» пролезет в критические моменты.

Бережное отношение к открытым проектам

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

SBOM, уровни зрелости и аттестации: что означают модные аббревиатуры

Перечень компонентов SBOM. Это «список ингредиентов» вашего продукта: какие пакеты и версии внутри. Полезен для быстрого ответа на вопрос «мы затронуты новой уязвимостью?» и для сравнения версий при выпуске. Генерируйте SBOM автоматически в конвейере и храните его вместе с артефактом.

Уровни защищённости цепочки поставок SLSA. Грубо говоря, шкала зрелости: от «мы хоть как-то собираем» до «у нас воспроизводимые сборки, аттестации и строгая верификация». Ориентир удобный: помогает поэтапно планировать улучшения, а не пытаться «сделать всё и сразу».

Аттестации происхождения. Идея простая: к артефакту прилагается подписанное описание, где и как он был создан — из какого репозитория, каким конвейером, каким пользователем или сервисом. Проверяя аттестацию, вы отсекаете «сиротские» сборки и подмены.

План реагирования: что делать, если всё же «прилетело»

Паника — плохой советчик. Нужна заранее отработанная последовательность действий. Сначала — вероятная зона поражения: какие продукты/версии/клиенты могли получить вредоносный артефакт, где он используется. Затем — блокировка распространения: остановка релизов, отозвать подписи, выключить зеркала, перекрыть публикации. Параллельно — ротация секретов: всё, к чему мог дотянуться атакующий через конвейер, меняется в первую очередь. После — чистая сборка: переобновить из проверенных исходников, переиздать с новыми ключами, приложить аттестации и перечни компонентов. И, конечно, коммуникация: честно и по делу. Ваши клиенты и внутренние команды должны знать, что именно произошло, как это распознать, что сделать сейчас и какова линия времени.

Типичные ловушки, из-за которых защита «бутафорская»

  • Подписи «для галочки»: подписываем, но нигде не проверяем автоматически.
  • Один и тот же токен везде: сборка, тесты, выкладка, публикация — всё под одной учёткой.
  • «Latest» в базовых образах и плавающие версии пакетов в проде.
  • Самописные плагины в конвейере без ревью и подписи.
  • Публичные регистраторы напрямую из сборки, без внутреннего зеркала и карантина.
  • Отсутствие планов реагирования: когда гром грянул, никто не знает, где ключи и кто «владелец релиза».

Что стоит внедрить уже сейчас (короткий чек-лист)

  • Фиксируйте версии зависимостей, новые версии проходят через карантин и автоматические проверки.
  • Подписывайте коммиты, релизы и артефакты. Без подписи — не запускаем.
  • Разделите конвейеры по ролям и секретам, используйте одноразовые окружения.
  • Включите защиту веток, обязательные ревью, многофакторную аутентификацию мейнтейнеров.
  • Откажитесь от «latest». Тяните контейнерные образы по дайджесту, держите внутренние зеркала.
  • Генерируйте и храните перечень компонентов SBOM для каждого релиза, проверяйте аттестации происхождения.
  • Держите наготове план реагирования: остановка релизов, отзыв ключей, чистая сборка, коммуникация.

Атаки на цепочку поставок — это новая норма повседневной разработки. Хорошая новость в том, что против них работают понятные, проверенные практики. Часть — сугубо техническая: подписи, аттестации, изоляция конвейеров, закреплённые версии, проверенные образы. Часть — организационная: правила внесения изменений, управление поставщиками, дисциплина релизов и честная обратная связь при инцидентах. Разделите меры на этапы, двигайтесь к целевому состоянию шаг за шагом и не забывайте про «план Б» на случай беды. Тогда доверие к вашим обновлениям будет оправдано не словами, а делом.

атака на цепочку поставок supply chain attack зависимости
Alt text
Обращаем внимание, что все материалы в этом блоге представляют личное мнение их авторов. Редакция SecurityLab.ru не несет ответственности за точность, полноту и достоверность опубликованных данных. Вся информация предоставлена «как есть» и может не соответствовать официальной позиции компании.

Порядок в задачах ИБ — это возможно!

Практический воркшоп 28 августа в 11:00 (мск): Как превратить хаос в задачах в управляемый процесс

Реклама.18+. ООО «СЕКЪЮРИТМ», ИНН 7820074059


Техно Леди

Технологии и наука для гуманитариев