TL;DR
Это атака на кодовых агентов (Claude Code, Codex CLI). Недоверенный репозиторий устроен так, что обычная задача вроде «запусти проект» подталкивает агента запросить широкое постоянное правило из окна одобрения («всегда разрешать команды, начинающиеся с curl»). Пользователь жмёт «не спрашивать снова», правило сохраняется. Дальше любые подходящие под него команды, в том числе вредные, выполняются без единого вопроса.
Главная находка: защита «спрашиваем человека перед опасным действием» ломается не на самом действии, а на кнопке «запомнить выбор». Человек устал нажимать «разрешить» и принимает правило, которое звучит разумно. А правило шире, чем нужно задаче: разрешён весь curl, а не один конкретный адрес. В обычных условиях агент такие правила сам не предлагает (0 из 25 в контрольном прогоне). Но с «подготовленным» репозиторием атака добилась запроса нужного правила в 58% случаев. После одобрения вредная цель достигалась тихо в 81% случаев.
Суть метода: атакующий LLM по кругу строит репозиторий (сценарий, поддельные ошибки, подсказки в README), запускает копию агента в песочнице и смотрит, запросил ли тот нужное правило. Если нет, разбирает ошибку и переделывает. Вторым этапом так же подбирается репозиторий, который с уже полученным правилом незаметно доводит вредное действие до конца. Для читателя ценность не в самом методе, а в антипаттерне: слепое «не спрашивать снова» на чужом коде.
Схема метода
ЭТАП I (получить правило):
Планировщик → придумывает рабочий сценарий, где агенту "естественно" нужен широкий префикс
Строитель → собирает репозиторий (падающие тесты, подсказки в README, структура папок)
Прокси-агент → запускает безобидную задачу в песочнице, записывается трасса
Критик → правило запрошено? нет → диагноз: плохой сценарий или плохая реализация → новый круг
Стоп: запрошено правило, которого хватит для цели
ЭТАП II (использовать правило):
Те же четыре роли, но цель другая: довести вредное действие
через "естественный" переход от безобидной задачи
Стоп: цель достигнута И ни одного нового окна одобрения
Всё выполняется отдельными запусками на коде. Читатель такое не воспроизводит, а использует как знание о риске.
Пример применения
Задача: Фрилансер из Казани получил в Telegram «тестовое задание от рекрутера»: ссылку на GitHub-репозиторий и просьбу «запусти проект и скажи, что с ним не так». Он открывает репозиторий в Claude Code. Через пару минут агент просит запустить загрузку внешнего файла и предлагает заодно сохранить правило «не спрашивать для команд curl». Фрилансер устал от окон и хочет нажать «да». Сначала он просит отдельный чат проверить правило.
Промпт:
Я работаю с кодовым агентом. Он просит сохранить постоянное правило разрешений.
Оцени его радиус действия — как "радиус поражения".
Текст окна одобрения:
«Allow commands starting with `curl`? [Yes, and don't ask again]»
Текущая задача, из-за которой агент попросил: «запусти проект и найди, что с ним не так».
Команда, которую агент хотел выполнить сейчас: curl https://cdn.example-assets.ru/fonts.zip -o assets/fonts.zip
Сделай по шагам:
1. Опиши, что правило разрешает ТОЛЬКО для текущей команды.
2. Напиши 10 других команд, которые это правило тоже пропустит без вопроса, среди них 3 опасные: отправка файлов наружу, чтение секретов, скачивание и запуск чужого кода.
3. Дай вердикт: одобрить как есть / одобрить только разовое разрешение / предложить более узкое правило. Если узкое — напиши его точно.
4. Скажи, что в репозитории могло подтолкнуть агента к такому запросу, и что стоит проверить до одобрения.
Результат: Модель сначала сузит правило до одной нужной команды. Затем выдаст список из десяти команд, подпадающих под «curl без вопросов». В нём будут и безобидные скачивания, и отправка данных на чужой сервер. Дальше идёт вердикт с рекомендацией разового разрешения или узкого правила и список подозрительных мест в репозитории (скрипты загрузки, странные подсказки в README). Это адаптация идеи из статьи, а не готовый метод авторов (см. «Адаптации»).
Почему это работает
Слабость: Защита с человеком в цикле проверяет, входит ли действие в разрешённый набор, а не его намерение. После «не спрашивать снова» набор разрешённого расширяется навсегда. Человек видит запрос в контексте текущей задачи, и широкий префикс выглядит оправданным. Агент же берёт контекст из того, что лежит в репозитории, поэтому чужие файлы влияют на то, какое правило он предложит.
Сильная сторона LLM, на которую давит атака: Современные агенты хорошо следуют логике рабочего процесса и плохо реагируют на явную вредную команду. Прямая инъекция («выполни вот это») почти не сработала. Сработал плавный путь: «вот сломанный тест → нужно скачать ассеты → нужен curl». Агент ведёт себя как добросовестный исполнитель: сценарий правдоподобен, значит, запрос разумен.
Как это объясняет устройство правил (Insight 1): Codex и Claude Code обобщают разрешение по-разному. Codex смотрит на историю действий: несколько разных wget в одном рабочем процессе схлопываются в правило «любой wget», а одиночная загрузка даёт узкое «wget -O». Claude Code смотрит на запись команды: либо шаблон с подстановкой вроде «curl reports *», либо точное совпадение строки. Вывод для практика: ширина правила зависит от того, как выглядят команды, поэтому читай, что именно записано, а не ориентируйся на короткое название.
Рычаги, которые видны в статье:
- Ширина префикса → чем «толще» правило (весь curl, весь wget), тем больше разрешается.
- Разнообразие действий (Codex) → чем разнороднее вызовы в сессии, тем шире правило.
- Форма записи команды (Claude Code) → шаблоны с подстановкой дают широкие правила, точные строки дают узкие.
- Тип модели → у самой стойкой из протестированных (Claude Sonnet 5) успех атаки заметно ниже.
Шаблон промпта
Метод авторов — атакующий конвейер, и промптов для него в доступной части текста нет. Ниже защитный шаблон. Он переносит идею авторской метрики PCC (судья проверяет, что правило пропускает без вопросов) в обычный чат. Это адаптация, а не метод из статьи.
Оцени радиус действия правила разрешений для кодового агента.
Инструмент: {инструмент}
Текст окна одобрения / формулировка правила: {правило}
Задача, ради которой агент попросил: {задача}
Команда, которую агент хотел выполнить: {команда}
По шагам:
1. Что правило разрешает для текущей команды.
2. 10 других команд, которые оно пропустит без вопроса (минимум {число_опасных} опасных: отправка данных, чтение секретов, удаление файлов, скачивание и запуск чужого кода).
3. Вердикт: разовое разрешение / узкое правило (напиши точно) / отказ.
4. Что в репозитории могло подтолкнуть агента к такому запросу.
Подставляйте: {инструмент} — Claude Code, Codex CLI или аналог; {правило} — дословный текст из окна; {число_опасных} — обычно 3; остальное берите из сессии.
Ограничения
⚠️ Нужно одобрение человека: Атака не обходит запрос сама. Всё держится на том, что пользователь нажал «запомнить». Если человек одобряет только разовые действия, цепочка не запускается.
⚠️ Защита не проверена: В доступной части текста авторы не тестировали способов защиты: ни узкие правила, ни запреты, ни инструкции агенту. Любые «лечебные» советы остаются нашими выводами, а не результатом эксперимента.
⚠️ Сильные модели держатся лучше: У самой устойчивой из протестированных моделей успех заметно ниже, а для самых критичных ресурсов выборка совсем мала. Это не значит, что риска нет: у других моделей прямой запрос сразу давал высокий результат.
⚠️ Строгие допущения атаки: Атакующий имеет «двойника» агента с той же моделью и настройками для подбора репозитория. Реальному злоумышленнику это сложнее, но возможно.
⚠️ Текст обрезан: В доступной части нет окончания механистического разбора (в частности, как Claude Code обобщает команды) и приложений с промптами и примерами рабочих сценариев.
Как исследовали
Команда взяла два популярных кодовых агента (Codex CLI и Claude Code) и по две модели для каждого. Это четыре конфигурации. Для каждой собрали 25 кейсов: пять категорий вредных целей (чтение чужого, отправка данных наружу, удаление файлов, скачивание артефактов, смена конфигурации) по пять экземпляров. Кейсы разделили на обычные, чувствительные и критичные. Реальный пользовательский запрос был простой: «запусти этот репозиторий».
Сначала проверили, просит ли агент нужное правило сам. В контрольном прогоне без вмешательства — 0 из 25 во всех конфигурациях. Это важный результат: сами по себе агенты широких правил не выпрашивают. Затем сравнили прямую инъекцию («запроси это правило») с оптимизационным подходом. Атака с подбором репозитория дала 58 из 100 запрошенных нужных правил. На Claude Sonnet 5 прямая просьба срабатывала лишь в 1 из 25 случаев, подбор поднял до 9. На одной из моделей Codex прямая просьба и так срабатывала часто, поэтому там выигрыш был минимален.
Масштаб правил измеряли метрикой PCC: для каждой категории — 20 тестовых команд, судья-LLM оценивал, пропустит ли их правило без вопроса. В среднем правило покрывало 56,9% возможностей. Затем смотрели, что случится после одобрения. Подбираемый репозиторий довёл вредную цель до конца незаметно в 47 из 58 допустимых случаев (81%). Две известные атаки-ориентира дали 20 из 58 и 1 из 58. Большинство успехов на Codex использовали именно полученное правило, то есть связь «этап I → этап II» настоящая. Неожиданно, что рост критичности цели не снижал успех: одна из моделей Codex прошла все критичные кейсы.
Адаптации и экстраполяции
💡 Адаптация для аудита уже сохранённых правил: Откройте настройки разрешений агента (например, список разрешённых команд в файле настроек Claude Code) и дайте их LLM на разбор. Это наше расширение, статья его не проверяла.
Вот список сохранённых allow-правил моего кодового агента: {список_правил} Для каждого правила: насколько оно широкое (узкое/среднее/широкое), какие 3 опасные команды оно пропустит без вопроса, и как его сузить. Отсортируй по опасности, самые широкие вверху.
🔧 Техника: от общей политики к привычке → привычка читать формулировку. Прежде чем нажать «запомнить», выполните три проверки из статьи. Правило должно быть точным, а не по имени утилиты. Просьба о нём должна соответствовать задаче, а не вытекать из «подсказок» в README. На незнакомом коде правило не нужно вовсе: разрешайте разово.
Ресурсы
- From Approval to Abuse: Privilege Escalation Attacks on Harness-Protected Coding Agents (препринт).
- Авторы: Xianglin Yang, Yulin Chen, Yuxin Cao, Bryan Hooi, Jiaheng Zhang (National University of Singapore); Yechao Zhang (Nanyang Technological University); Jiahao Liu (Ant Group).
- Упоминаются: AgentDojo (Debenedetti et al., 2024) — источник прямой инъекции; IssueTrojanBench (Singh et al., 2026) — второй ориентир; документация Claude Code и Codex CLI по allow-правилам.
