Дыра в Claude Code: сообщение на GitHub добирается до ключей сборки
Заявки в баг-трекере GitHub, открытой человеком без единого права на репозиторий, оказалось достаточно, чтобы добраться до секретов его сборочного конвейера. Novee Security показала это на Black Hat USA 5 августа 2026 года сразу на трёх ИИ-агентах для кода: Claude Code от Anthropic, Gemini CLI от Google и Codex от OpenAI. Ни одна из атак не сломала саму модель. Сломали обвязку вокруг неё - обычный код, который решает, какие команды модели разрешено выполнять.
Как сообщение на GitHub добирается до секретов CI
Все три агента подключаются к непрерывной интеграции одинаково. Событие в репозитории, заявка (в интерфейсе GitHub она называется issue) или пул-реквест, запускает workflow, workflow поднимает агента на раннере, и агент читает текст события как часть задачи. Этот текст пишет тот, кто открыл заявку. В публичном репозитории - вообще кто угодно.
Инъекция промпта через такой текст - известная проблема, и у каждого из этих инструментов есть слой проверки, который должен её сдерживать. Исследование как раз про то, что слой не сработал, а не про доверчивость модели. На раннере лежат учётные данные, нужные конвейеру: токены репозитория, ключи от облака, API-ключи самого агента. Кто выполнил на раннере команду, добрался до всего этого.
Дыра в Claude Code: расхождение из-за кавычек и счётчик загрузок
Цепочка в Claude Code началась с разногласия по поводу кавычек. Валидатор команд срезал текст в одинарных кавычках до того, как применить свои двадцать три проверки, исходя из того, что оболочка сочтёт содержимое кавычек безобидными данными. А дальше обвязка передавала команду уже без этих кавычек. Значение, спрятанное во флаге --receive-pack у git, поэтому выглядело безобидно при проверке и выполнялось на раннере.
Дальше начинается самое интересное. Anthropic выпустила патч, и исследователи нашли второй путь через tac - команду только на чтение, которая переворачивает содержимое файла, - и напечатали API-ключ задом наперёд в публичный лог сборки. Это тоже закрыли. Третий заход, известный как CVE-2026-54316, вообще отказался что-либо печатать: ключ утёк по одному символу через публичный счётчик загрузок модели на Hugging Face, а ответ читали снаружи. Оценка - 9,1 по CVSS v3.1 и 6,0 по CVSS v4; Anthropic относит проблему к умеренным на том основании, что атакующему сначала надо протащить недоверенный текст в контекст агента. Затронуты выпуски начиная с 0.2.54, исправление приехало в 2.1.163, бюллетень GHSA-fg94-h982-f3mm.
Gemini CLI: худшая оценка из трёх
Инструменту Google досталось жёстче. У CVE-2026-12537 оценка 10,0 по CVSS: запускатель контейнера разбирал белый список инструментов один раз, при регистрации, и ничего не проверял во время работы. Под флагом --yolo любая запрошенная моделью команда одобрялась автоматически, а инъекция команд ОС через подготовленный файл .gemini/.env выполняла код на хосте CI ещё до того, как поднималась песочница. Уязвимы все версии по 0.39.0 включительно, исправление в 0.39.1, GitHub Action обновлён до run-gemini-cli 0.1.22, бюллетень GHSA-wpqr-6v78-jr5g.
С Codex вышло иначе. Два прохода Codex делили один checkout в рамках одной задачи, поэтому первый проход мог записать файл AGENTS.md, который второй затем загружал как инструкции. Позиция OpenAI: песочница вела себя ровно так, как описано в документации, поэтому патча версии не выпускали. Вместо этого поменяли рекомендации по workflow: проходы разнесли по разным задачам, а файлы инструкций в репозитории прямо назвали частью недоверенной поверхности ввода.
Почему украденный доступ продолжает работать
Отдельное исследование Silverfort, опубликованное 28 июля 2026 года, объясняет, почему одна кража стоит так дорого. На macOS Claude Code CLI кладёт свой OAuth-набор в Keychain как generic password под именем службы "Claude Code-credentials", создавая запись через /usr/bin/security без аргументов контроля доступа. Запись наследует список доступа по умолчанию, который доверяет создавшему её инструменту. А поскольку этот инструмент - универсальный бинарник Apple, вызвать который может любой процесс, одна строка в терминале возвращает весь набор без Touch ID и без пароля.
В наборе лежит короткоживущий access-токен и долгоживущий refresh-токен, а вместе с ними учётные данные подключённых MCP-серверов. Проблема именно в refresh-токене: его можно менять на новые access-токены, пока кто-нибудь не отзовёт, и он не привязан ни к устройству, ни к адресу. Anthropic не считает это уязвимостью, исходя из того, что процессы под тем же пользователем и так доверенные, но сообщила, что ужесточение контроля доступа отслеживается как улучшение защиты в глубину. Стоит заметить, что собственное десктопное приложение компании сделано иначе: токены там лежат зашифрованными ключом, привязанным к подписи кода, и попытка чужого процесса добраться до ключа вызывает запрос пароля.
Что делать тем, кто гоняет таких агентов
- Сначала обновиться: Claude Code 2.1.163 или новее, Gemini CLI 0.39.1 вместе с run-gemini-cli 0.1.22. Для Codex ставить нечего, там надо менять сам workflow.
- Не давать публичным событиям запускать агента: workflow, который стартует от любой заявки или пул-реквеста из любого аккаунта, отдаёт поверхность ввода посторонним. Нужен ярлык, комментарий мейнтейнера или проверка на форк.
- Урезать секреты раннера: выдавать задаче самый узкий токен, с которым она справится, и держать долгоживущие облачные ключи подальше от workflow, куда дотягивается агент.
- Разносить проходы: если два запуска агента делят один checkout, первый может записать инструкции, которым подчинится второй. Разные задачи, разные checkout.
- Ротировать по подозрению, а не по доказательству: выйти из аккаунта, зайти заново, потом сменить ключи в консоли. Чистка машины не отзывает refresh-токен, который уже уехал.
- Следить за одной сессией на двух машинах: повтор учётных данных с разных хостов - тот самый признак, который эти токены делают возможным, потому что ничто не привязывает их к устройству.
Почему это важно не только разработчикам
Схема здесь та же, что повторяется по мере роста самостоятельности агентов: атака приходит не по сети трафиком, который можно осмотреть, а приходит контентом и выполняется внутри уже доверенной сессии. Мы писали про ту же форму, когда ИИ-браузер угоняли постом, по которому пользователь не кликал, и по той же причине опасна цепочка вроде дыры в форме входа WordPress, которая доводит до кода на сервере, хотя ей и нужно, чтобы администратор просто открыл страницу. Здесь же проходит честная граница сетевых инструментов приватности. VPN прячет трафик от сети, в которой вы сидите, и меняет видимое местоположение, но он никак не видит, что решил выполнить ваш собственный агент, и не встаёт между процессом и связкой ключей на том же ноутбуке. Шифрование канала никогда и не было той границей, которую эти атаки переходят.
Вывод
• Claude Code and Gemini CLI Flaws Let a GitHub Issue Reach CI Workflow Secrets - The Hacker News
• Critical Flaws in Claude Code, Gemini CLI, and OpenAI Codex Enable RCE and Supply Chain Attacks - GBHackers
• Skipping the lock: A Claude Code CLI weakness lets any macOS process read stored credentials - Silverfort