Почему безопасностью пайплайна нельзя ограничиваться защитой репозитория
CI/CD-пайплайн давно перестал быть просто последовательностью команд, которая собирает приложение и отправляет его на сервер. Сегодня это сложная цепочка автоматизированных процессов: система получает исходный код, устанавливает зависимости, запускает тесты, формирует артефакты, обращается к облачным сервисам и разворачивает результат в целевой среде.
На каждом этапе используются учетные данные, токены, разрешения и внешние инструменты. Именно поэтому пайплайн становится привлекательной мишенью для злоумышленников. Чтобы получить доступ к продакшену, необязательно атаковать сам сервер или искать уязвимость в пользовательском интерфейсе.
Иногда достаточно изменить один файл конфигурации, подменить зависимость или воспользоваться слишком широкими правами сервисного аккаунта. При этом многие команды по-прежнему воспринимают CI/CD как технический механизм, а не как часть периметра информационной безопасности.
Репозиторий защищен, к облаку подключена многофакторная аутентификация, секреты хранятся в специальном хранилище - кажется, что основные риски закрыты.
Однако слабое место может находиться между этими компонентами, в процессе их взаимодействия. Моделирование угроз помогает посмотреть на пайплайн глазами атакующего.
Важно заранее понять, какие элементы цепочки можно изменить, где хранятся чувствительные данные, какие действия выполняются автоматически и что произойдет, если один из этапов окажется скомпрометирован.
Сценарии атак, которые часто остаются за пределами внимания
Проблема CI/CD-безопасности заключается не только в наличии уязвимостей, но и в неправильной оценке вероятных сценариев.
Защита обычно строится вокруг очевидных угроз: кражи пароля разработчика, взлома Git-сервера или уязвимости в веб-приложении. Но атакующий может выбрать менее заметный путь - например, воздействовать на процесс сборки или на инструменты, которым доверяет команда.
Компрометация исходного кода и конфигурации
Первый очевидный объект атаки - репозиторий. Если злоумышленник получает возможность изменить код, он может внедрить вредоносную логику непосредственно в приложение. Но опасность представляет не только основной исходный код.
Не меньший интерес имеют файлы пайплайна, скрипты сборки, Dockerfile, конфигурации инфраструктуры и файлы управления зависимостями.
Изменение одного шага в workflow способно незаметно добавить отправку переменных окружения на внешний сервер, создать дополнительную учетную запись или ослабить проверки перед публикацией.
Причем такая правка может выглядеть как обычное техническое изменение и не вызвать подозрений при поверхностном просмотре. Особенно рискованны пайплайны, в которых действия запускаются для pull request из внешних репозиториев.
Если workflow автоматически получает доступ к секретам или обладает правами записи, атакующий может подготовить специально сформированный запрос на слияние и использовать его как промежуточный этап атаки.
Зависимости как скрытый канал проникновения
Современные проекты редко состоят только из собственного кода. Они используют библиотеки, плагины, контейнерные образы, готовые actions и пакеты из публичных реестров. Каждая такая зависимость расширяет поверхность атаки. При этом разработчики часто доверяют компонентам лишь потому, что они популярны или давно присутствуют в проекте.
Злоумышленник может внедрить вредоносный код в новую версию пакета, захватить учетную запись сопровождающего проекта или опубликовать библиотеку с названием, похожим на настоящее.
Если сборка автоматически устанавливает зависимости без фиксации версий и проверки контрольных сумм, подмена способна пройти незаметно. Отдельная проблема - транзитивные зависимости. Команда может напрямую использовать всего несколько библиотек, но каждая из них подтягивает десятки дополнительных компонентов.
В результате реальный состав программного обеспечения оказывается значительно шире, чем кажется, а контроль над ним становится формальным.
Утечки секретов во время сборки
Секреты часто защищают на уровне хранилища, но забывают о моментах их использования.
Токен может случайно попасть в логи, кэш, собранный артефакт, временный файл или сообщение об ошибке. Если один из этапов пайплайна выполняется сторонним инструментом, невозможно автоматически считать его безопасным только потому, что он подключен к доверенной системе.
Опасность возникает и при чрезмерной передаче переменных окружения.
Скрипту может требоваться один ключ, но вместо этого ему доступны сразу все секреты job или всего проекта. В случае компрометации такого шага атакующий получает гораздо больше возможностей, чем было необходимо для выполнения конкретной задачи.
Нередко секреты оказываются в истории коммитов. Даже если разработчик удалил ключ из текущей версии файла, он может сохраниться в старом коммите, кеше сборки или опубликованном артефакте.
Поэтому удаление строки из репозитория не означает, что учетные данные стали безопасными.
Доверие между компонентами - главный источник скрытого риска
В CI/CD-среде доверие распределено между множеством элементов. Система контроля версий доверяет runner, runner обращается к реестру образов, сборка использует внешние пакеты, а платформа развертывания принимает сформированный артефакт. Если хотя бы один компонент скомпрометирован, он может повлиять на последующие этапы цепочки.
На практике это означает, что безопасность нужно оценивать не только по отдельным сервисам, но и по связям между ними.
У защищенного репозитория могут быть небезопасные runner. У надежного облака - слишком привилегированный токен. У проверенного образа - неизвестный процесс его сборки.
Может быть интересно: Создание и разработка сайтов: от идеи до готового продукта
Самостоятельно размещенные runner
Self-hosted runner дает больше контроля над окружением, но одновременно становится отдельной машиной, которую необходимо защищать и обслуживать. На нем могут оставаться исходники, токены, временные файлы, кеши зависимостей и результаты предыдущих задач.
Если runner используется для разных проектов или не очищается после выполнения job, один процесс может получить доступ к данным другого.
Еще опаснее ситуация, когда на постоянном runner выполняется код из непроверенных pull request. В этом случае автор изменения потенциально получает возможность исследовать окружение, читать локальные файлы или атаковать соседние задачи. Для снижения риска runner следует изолировать, регулярно обновлять, ограничивать его сетевые подключения и не использовать один и тот же исполнитель для задач с разным уровнем доверия.
В чувствительных сценариях предпочтительнее краткоживущие одноразовые окружения.
Артефакты и контейнерные образы
После сборки результат обычно передается дальше: в хранилище артефактов, контейнерный реестр или систему развертывания.
Этот объект часто воспринимают как готовый и проверенный продукт, хотя на самом деле он может быть подменен между этапами. Если система развертывания не проверяет происхождение артефакта, злоумышленник способен заменить файл на аналогичный по имени и версии.
Еще один вариант - изменить образ в реестре после прохождения тестов. В итоге команда уверена, что запускает проверенную сборку, хотя фактически используется другой объект.
Надежная схема должна включать неизменяемые версии, цифровую подпись, проверку дайджеста образа и связь артефакта с конкретным коммитом. Важно также ограничить права на публикацию и удаление объектов в реестре.
Как подойти к моделированию угроз на практике
Моделирование угроз не обязательно начинать с создания сложной схемы, включающей все внутренние сервисы компании. Гораздо полезнее описать реальный путь изменения: от коммита разработчика до запуска приложения в рабочей среде. Для каждого этапа нужно зафиксировать, какие данные проходят через него, кто может его изменить и какие полномочия используются.
Затем стоит задать несколько простых вопросов. Может ли внешний пользователь инициировать выполнение этого шага?
Какие секреты доступны процессу? Можно ли повторно использовать его окружение? Кто имеет право изменить конфигурацию?
Проверяется ли источник артефакта перед развертыванием? Ответы помогают обнаружить риски, которые не видны при проверке отдельных систем.
Полезно разделять угрозы по последствиям: кража секретов, изменение исходного кода, подмена сборки, получение доступа к инфраструктуре, нарушение доступности и незаметное присутствие в системе. Такой подход позволяет определить приоритеты и не тратить ресурсы только на формальные настройки.
Главная идея заключается в том, что пайплайн необходимо считать производственной системой с высоким уровнем доверия.
Он способен самостоятельно выполнять действия от имени компании, обращаться к инфраструктуре и выпускать программный продукт. Поэтому его защита должна включать не только контроль доступа к репозиторию, но и проверку всех автоматических переходов, зависимостей, runner, секретов и артефактов.
Именно в этих связях чаще всего и прячутся угрозы, о которых вспоминают уже после инцидента.









