Codex - агент с доступом к локальным данным и инструментам, и это задаёт его модель угроз. Любой недоверенный текст может попытаться изменить план агента: веб-страница, issue, README пакета, сгенерированный файл, тестовая фикстура, лог, ответ MCP-сервера или инструкция из чужой ветки репозитория. Prompt injection - это попытка заставить агента принять такой текст за управляющую команду. Ключевое понимание всей главы: недоверенный контент - это данные, а не команды.
Опасность инъекции не постоянна, а зависит от того, что у агента есть под рукой. Injection становится куда опаснее, когда у агента одновременно есть секреты, доступ на запись и сеть. По отдельности каждый из этих факторов ограничивает ущерб: без сети украденное некуда отправить, без записи нельзя закрепиться, без секретов нечего красть. Вместе они складываются в реальный риск, поэтому их и разносят: одновременное наличие всех трёх - это то, чего избегают в недоверенном контексте.
Отсюда следует главный тезис о границе безопасности. Реальная граница проходит не в системном промпте, который инъекцией можно обойти, а в permissions, sandbox и execpolicy. Просить модель "не поддавайся на вредные инструкции" - это не защита: достаточно одной удачной формулировки, чтобы обойти просьбу. А вот техническая граница - выключенная сеть, deny на секреты, forbidden на опасную команду - держится независимо от того, что написано в недоверенном тексте. Защищает механизм, а не увещевание.
| Источник недоверенного текста | Почему опасен |
|---|---|
| Web page, package README | Может нести инструкции под видом контента |
| Issue, чужая ветка, repo instruction | Написан кем-то другим, вне вашего контроля |
| Generated file, test fixture, log | Легко упустить как "своё", хотя содержимое внешнее |
| MCP response | Ответ внешнего сервера - тоже недоверенные данные |
Секреты подчиняются простому правилу: их не должно быть там, откуда модель их прочитает. Не вставляйте ключи в prompt, инструкции, skill, определение агента, закоммиченные настройки, снапшот теста или лог. Используйте secret store и инъекцию из окружения, а на чувствительные пути ставьте deny в профиле. Deny-read для .env и ключей - полезный baseline, но не единственная защита: секрет, которого нет в контексте, невозможно утащить инъекцией, даже если она сработала.
Сторонний код требует той же настороженности, что и любой недоверенный ввод. Hooks запускают реальные локальные команды с правами процесса Codex - это не безобидные заметки, а исполняемый код. Non-managed hooks требуют ревью точного хэша определения, и после любого изменения они снова становятся untrusted, пока их не пересмотрели. Это защита от тихой подмены: изменённый hook не начинает исполняться молча, а требует нового явного доверия к своему новому содержимому.
Установка плагина - это не автоматическое доверие его начинке. Plugin может привезти skills, агентов, MCP и hooks разом, и наличие плагина в источнике не означает, что кто-то проверил безопасность его bundled hooks. Их доверие оценивают отдельно, как и любой исполняемый код. Отсюда дисциплина: закреплять и просматривать источник, изучать, что именно привозит плагин, начинать с тестового окружения и не путать "установилось" с "проверено и безопасно".
Практический вывод - переносить повторяемые решения из случайных промптов в правильный слой. То, что вы каждый раз объясняете агенту вручную, лучше выразить один раз в config, инструкциях, skill, custom agent, plugin, hook или MCP - там, где это будет видимым, проверяемым и переживёт сессию. Случайный prompt легко потерять и невозможно отревьюить; политика в правильном слое, наоборот, читается, тестируется и объясняется. Безопасность - это архитектура из слоёв, а не удачная формулировка.
Типичные провалы вокруг доверия предсказуемы. Положиться на просьбу к модели вместо технической границы в permissions и sandbox. Держать одновременно секреты, запись и сеть в недоверенном контексте. Вставить ключ туда, откуда модель его прочитает. Принять установленный плагин или изменённый hook за доверенный без ревью. И держать политику в случайных промптах вместо слоя. Трактуйте недоверенный контент как данные, держите границу в механизмах, разносите секреты, запись и сеть и переносите решения в правильный слой.