Последние несколько недель тема AI-агентов и postinstall-скриптов не даёт покоя. И вот, реальность решила объединить оба этих кошмара в одном инциденте: обновление Gemini CLI и последующая необходимость доверять модели из-за CVE с критическим рейтингом 10.0. Ситуация, когда две, казалось бы, полезные практики превращаются в опасную комбинацию, заставляет пересмотреть многие привычные подходы к безопасности разработки.

Для начала стоит признать: использование AI для ревью pull request — это действительно хорошая практика. Автоматизированные инструменты на базе LLM способны быстро оценить изменения в коде, снизить когнитивную нагрузку на разработчиков и помочь выявить потенциальные проблемы. Крупные организации, такие как Red Hat, уже внедрили рабочие процессы, где Gemini анализирует каждый открытый PR. Однако, как только в этих инструментах появляется уязвимость или они используются неправильно, вся конструкция рушится.

Проблема коренится в том, как AI-инструменты интегрируются в CI/CD. Чтобы запустить Gemini CLI в headless-режиме (без интерактивного управления), необходим так называемый YOLO-режим. Этот режим, по замыслу разработчиков, позволяет CLI выполнять произвольные команды на системе — и это нормально для CI/CD. Но что произойдёт, если злоумышленник контролирует содержимое pull request?

Управление настройками AI-агента осуществляется через файл settings.json. Это обычный, безобидный на вид JSON-файл, в котором указываются предпочтения: включить Vim mode, выбрать тему оформления, разрешить набор инструментов в Docker-песочнице. Однако в классическом стиле инструментов CLI здесь присутствуют «хуки» (hooks). Среди них — before_agent или before_tool. Хук before_agent выполняется после отправки запроса пользователем, но до начала планирования работы агента. И этот хук может содержать команду, например, security_check, которая произвольным образом исполняется на системе. Пока автором кода являетесь вы, это допустимо. Но когда речь идёт о pull request, код контролирует уже кто-то другой — потенциальный злоумышленник.

До того как уязвимость была исправлена, атакующий мог отправить вредоносный pull request с особым settings.json. GitHub workflow, настроенный на автоматическое ревью (например, как в гипотетическом примере с Red Hat), запускал бы Gemini CLI, который в свою очередь выполнял команду из хука. В результате злоумышленник получал возможность произвольного выполнения кода внутри CI/CD runner’а, работающего от имени организации. Через раннер можно извлечь токены доступа, API-ключи, переменные окружения и любые другие чувствительные данные, присутствующие в окружении.

Контекст: Team PCP и эпидемия supply chain-атак

Этот инцидент не случаен. Он вписывается в более широкий паттерн атак на цепочки поставок, за которыми стоит угрожающий актор Team PCP. За последние месяцы эта группа стояла за компрометацией нескольких популярных инструментов разработки: lightLLM, утилит Trivy, инструмента Checkmarx (SCA-решение) и Telníx. Все эти атаки объединяет одно — скомпрометированный CI/CD пайплайн или вредоносное GitHub-действие.

Например, в марте этого года Team PCP использовала уязвимость в сервисе Aquabot для атаки на репозиторий Trivy Action. Затем была скомпрометирована сама Aqua Security через Trivy, что привело к каскадным последствиям. Аналогично, компрометация Axios workflow произошла из-за использования подкапотного Checkmarx инструмента. Общая закономерность такова: компании внедряют «хорошие» средства разработки и безопасности, но делают неверные предположения о доверии к коду, который эти средства обрабатывают.

Как работают CI/CD раннеры и в чём риск

Типовой CI/CD workflow получает код из PR и запускает его на раннере. GitHub по умолчанию предоставляет облачные раннеры. Однако крупные организации часто настраивают self-hosted раннеры — собственные машины в инфраструктуре, которые выполняют задачи. Именно здесь кроется дополнительный риск. Если злоумышленник получает выполнение кода на self-hosted раннере, он может атаковать другие процессы, работающие на том же уровне привилегий, и похитить их учётные данные: пароли к базам данных, API-ключи, токены облачных провайдеров.

Проблема усугубляется тем, что многие конвейеры проектируются в предположении, что исполняемый код является доверенным. Но при появлении уязвимости вроде описанной (или любой другой, позволяющей выполнить произвольные команды) это предположение становится фатальным.

Что делать: принцип тотального компромисса и практические меры

Единственный разумный ответ на подобные угрозы — принять, что всё уже скомпрометировано. Исходить из того, что любой запущенный код может привести к взлому. Дальше нужно ответить на вопрос: если злоумышленник попадёт в ваш раннер (облачный или self-hosted), что он сможет украсть и как далеко продвинется?

Из этого следуют конкретные шаги:

  1. Минимизация привилегий. Используйте Linux-модель прав доступа. Создавайте отдельных пользователей для разных процессов, чтобы компрометация одного не вела к краже учётных данных другого.
  2. Правильная песочница. Если вы используете self-hosted раннеры, обязательно запускайте их внутри Docker-контейнеров или аналогичных изолирующих сред. Это ограничит влияние выхода за пределы раннера. И не запускайте Docker-контейнеры от root — это отдельная большая тема.
  3. Обновление версий. Google уже выпустил исправления. Добавлен флаг --trust-workspace, который по умолчанию отключён. Если вы абсолютно уверены, что PR приходят только от доверенных контрибьюторов, можно включить его. В остальных случаях необходимо использовать новые версии GitHub Action run-gemini-cli: версии 3.9.1 и 0.40-preview-3 и выше не доверяют настройкам рабочего пространства по умолчанию. Важно: если вы зафиксировали (запинили) конкретную версию Gemini CLI, необходимо повысить версию, так как все предыдущие версии уязвимы.

Обновляйте свои CI/CD workflow. Паттерн supply chain-атак с использованием AI-агентов и несанитизированных конфигурационных файлов только набирает обороты. Игнорировать его — значит играть в опасную лотерею.