Prompt injection — это не некорректный запрос, который можно удалить одним регулярным выражением. Это нарушение границы доверия: содержимое, которое нужно было считать данными, меняет поведение языковой модели. В AI-агенте такое изменение превращается в вызов инструмента, сообщение, запись файла или запрос к другому сервису. Model Context Protocol (MCP) упрощает обнаружение и вызов инструментов, но одновременно даёт недоверенному тексту больше путей к модели и привилегированным системам.
В статье рекомендации OWASP GenAI LLM Top 10 2026 применяются к агентам, которые читают внешний контент и используют MCP. Это инженерная модель угроз и руководство по защите, а не аудит безопасности. Ни один описанный контроль не гарантирует безопасность. Цель скромнее: предположить, что инъекция иногда повлияет на модель, и сделать последующее действие ограниченным, заметным, обратимым и трудным для злоумышленника.
Почему модель не является границей безопасности
LLM получает системные инструкции, запрос пользователя, найденные документы, описания и результаты инструментов, историю диалога и память в одном контексте. Разделители и метки могут сообщать политике доверия, но не создают архитектурную изоляцию. Модель может неверно понять метку, принять правдоподобную фразу в документе за команду или собрать опасный план из нескольких безобидных подсказок.
OWASP LLM01:2026 относит к prompt injection изменения поведения под влиянием прямого ввода, найденного контента, результата инструмента, изображения, аудио, видео, промежуточного контекста или долговременной памяти. Эта категория отличается от раскрытия чувствительной информации, чрезмерных полномочий и небезопасной обработки вывода, хотя в одном инциденте они соединяются. Инъекция создаёт влияние, инструмент даёт полномочие, секрет становится активом, а сетевой запрос, URL или команда оболочки может стать каналом утечки.
Модель не должна хранить учётные данные, принимать решение об авторизации или быть единственным валидатором операции, меняющей состояние. Такие решения нужно вынести в детерминированный код приложения. Оставьте модели интерпретацию и планирование, а окружающая система пусть принудительно определяет, что действительно разрешено.
Модель угроз агента с MCP
Начните с реального потока данных, а не со схемы, которая заканчивается на чате. Отметьте пользователя, провайдера модели, среду агента, MCP-клиент и серверы, сервер авторизации, внешние API, браузер, файловую систему, память, индекс поиска, логи и исходящий сетевой контур. Для каждого перехода укажите, создано ли содержимое пользователем, организацией, сторонним автором, публичным источником или неизвестным участником.
Атакующими могут быть вредоносный сайт или отправитель письма, автор тикета или репозитория, скомпрометированная зависимость или MCP-пакет, недобросовестный оператор инструмента, а также похититель токена или идентификатора сессии. Обычный пользователь тоже может непреднамеренно передать инъекцию, вставив документ с инструкциями для другой системы. Внутренняя база не становится чистой только потому, что закрыта авторизацией: запись туда могла попасть через публичную форму, синхронизацию или взломанную учётную запись.
Составьте отдельный список активов: инструкции системы и разработчика, токены, ключи, персональные данные, код, закрытые документы, метаданные облака, конфигурация инструментов, память и возможность отправлять, удалять, покупать, развёртывать или изменять. Для каждого актива укажите, можно ли его читать, записывать или наблюдать извне. Инструмент чтения тоже способен утечь, если его вывод отправляется на адрес злоумышленника. Уведомление становится опасным каналом, если принимает произвольные URL или текст.
Для каждого сценария запишите инвариант простыми словами: «суммировать тикет и не выполнять его инструкции», «читать только этот репозиторий», «подготовить письмо, но не отправлять без подтверждения». Рядом укажите условие отказа: секрет в аргументе инструмента, избыточный scope, запись вне рабочей области или адрес, не разрешённый политикой.
Полезная карточка риска содержит пять полей: поверхность доставки, распространение, кодирование, привилегии и канал воздействия. Доставка бывает через чат, веб-страницу, PDF, описание MCP-инструмента, ответ инструмента или память. Инъекция может пройти один шаг, цепочку, межсессионную запись памяти или сообщение другому агенту. Она может быть видимым текстом, HTML, невидимыми символами Unicode, низкоресурсным языком, изображением, аудио или обфускацией. Привилегии — это личность и scopes во время исполнения. Канал воздействия создаёт последствие.
Прямая и косвенная инъекция
Прямая инъекция приходит через пользовательский интерфейс. Пользователь может попросить игнорировать задачу, показать скрытые инструкции, выполнить неограниченную команду или использовать инструмент не по назначению. Сюда же относится добросовестная вставка текста, содержащего обращённую к AI инструкцию. Jailbreak — частный случай, где цель состоит в обходе защитной логики модели, но агенту можно навредить и без jailbreak. Вежливо выполненная ложная команда на возврат денег всё равно нарушает границу приложения.
Косвенная инъекция приходит из содержимого, которое пользователь не писал как инструкцию. Веб-страница может потребовать загрузить контекст агента. Вложение письма — запросить сброс пароля. Тикет поддержки — искать закрытый репозиторий. Такой текст может находиться в строке базы, заголовке issue, README пакета, изображении или ответе инструмента. Пользователь может не увидеть байты в HTML, метаданных, свёрнутом блоке, картинке или нулевой ширине Unicode.
MCP расширяет поверхность в двух направлениях. Сервер публикует имена, описания, схемы входа, ресурсы и промпты, которые клиент помещает в контекст модели. Отравленное описание может приказать сначала вызвать другой инструмент, добавить секрет в аргумент или доверять URL злоумышленника. Затем сервер возвращает результат, который модель может принять за новую инструкцию и сделать следующий вызов. Это отравление инструмента и инъекция через результат даже при корректном JSON-RPC.
Считайте метаданные инструмента влиянием, а не документацией. Фиксируйте версии пакетов, проверяйте серверы, анализируйте описания и схемы, сравнивайте релизы и ведите список разрешённых возможностей каждого сервера. Подпись помогает подтвердить происхождение, но не доказывает безвредность версии. Нужны проверка реализации и сетевого поведения.
Как влияние превращается в утечку
Prompt injection становится утечкой, когда соединяет источник с каналом воздействия. Источником может быть заражённый issue, который агент нашёл, а каналом — HTTP-запрос, письмо, публичный комментарий, приглашение календаря, URL изображения, запись лога или аргумент инструмента. Прямой доступ к приватным данным не нужен, если агент может их прочитать и связаться с внешним адресом.
Явно моделируйте «летальную триаду»: недоверенный контент, чувствительные данные и внешний или изменяющий состояние канал. Надёжнее убрать одну из частей, чем распознавать каждое вредоносное предложение. Агент для исследования может просматривать публичные страницы без входа и с ограниченной сетью. Сумматор закрытых документов может не иметь сети и права отправки. Агент, который пишет письмо, может создать черновик без разрешения отправлять его.
Одной фильтрации вывода недостаточно. Секрет может уйти в допустимом поле JSON, параметре URL, диагностике инструмента, изображении, пробелах, Unicode или обычном тексте письма. До канала воздействия проверяйте адрес и поток информации. Маскируйте секреты в логах и трассировках, а исходящие запросы направляйте через прокси, который блокирует приватные адреса, неизвестные домены и неожиданные методы.
Авторизация MCP и OAuth
Для защищённого HTTP-сервера MCP разделяйте роли протокола. MCP-сервер является resource server, клиент просит доступ от имени владельца ресурса, а authorization server выдаёт токены. Следуйте спецификации авторизации MCP и соответствующим требованиям OAuth, а не создавайте собственный прокси-поток.
Привязывайте токен к целевому MCP-ресурсу. Спецификация требует передавать канонический URI сервера в OAuth-параметре resource и в запросе авторизации, и в запросе токена. Сервер обязан проверять, что токен выпущен для него. Используйте заголовок Authorization, не строку запроса. MCP-сервер не должен принимать или пересылать токен другого ресурса. Для внешнего API нужен отдельный токен. Передача токена разрушает разделение аудиторий, ослабляет лимиты и аудит и может превратить сервер в прокси для утечки.
Защищайте authorization code с помощью PKCE, точных зарегистрированных redirect URI, HTTPS в production и криптографически случайного одноразового state. Прокси с динамической регистрацией клиентов должен получить согласие для каждого клиента до перенаправления к стороннему серверу авторизации. Привязывайте согласие к client ID и scopes. Общая cookie «приложение уже подтверждено» не подходит: она создаёт confused deputy.
Считайте discovery входом от сервера, а не доверенной конфигурацией. Разрешайте только безопасные схемы и известные хосты, отклоняйте javascript:, data: и file:. Защищайте серверные запросы от SSRF: блокируйте приватные, loopback, link-local и cloud-metadata диапазоны, проверяйте каждый redirect и используйте egress-прокси. Не открывайте URL через оболочку. Это обычные MCP-контрмеры, которые инъекция может попытаться обойти.
Используйте прогрессивные scopes. Начинайте с обнаружения и чтения, запрашивайте точное дополнительное право только при необходимости конкретной операции и записывайте запрошенное и выданное подмножество с correlation ID. Избегайте *, all и административных omnibus-scope. Claims не заменяют авторизацию на каждом инструменте и аргументе. Короткоживущие токены, защищённое хранилище, ротация refresh token для публичных клиентов и аккуратные логи ограничивают ущерб от кражи.
У локального MCP-сервера другая граница. Процесс может иметь права клиента, читать файлы, использовать сеть и запускать команды. До подключения покажите точную стартовую команду и аргументы. Предпочитайте stdio или защищённый IPC неавторизованному HTTP. Запускайте процесс в sandbox или контейнере с минимальными правами на файлы, сеть и процессы, выдавая дополнительные каталоги и адреса явно.
Многоуровневая защита
Минимальные привилегии ограничивают радиус поражения. Давайте агенту только инструменты одного сценария. Разделяйте чтение, подготовку, подтверждение и фиксацию изменения. Используйте короткоживущие учётные данные для операции вместо постоянного пользовательского токена. Проверяйте авторизацию ещё раз при исполнении, потому что план модели, сессия, описание инструмента или ресурс могли измениться.
Gate подтверждения должен быть настоящей политической проверкой. Требуйте его для отправки, удаления, публикации, платежа, изменения прав, развёртывания, доступа к новому классу данных или нового адресата. Показывайте точное действие, аргументы, личность, цель, поля данных и побочный эффект, а не только резюме модели. После подтверждения пересчитайте preview и привяжите его к хэшу операции, чтобы следующий шаг не заменил аргументы. Ограничивайте частоту малорисковых действий, но не приучайте проверяющих одобрять поток непрозрачных окон.
Изоляция ограничивает последствия успешной инъекции. Разделяйте клиентов, сессии и хранилища памяти. Агент браузинга не должен иметь приватных ключей. Для coding-агента задайте узкую рабочую папку, сеть по умолчанию запретите и используйте отдельную идентичность для установки пакетов. Сочетайте изоляцию процесса, файлов, сети и браузера. Контейнер сам по себе не является политикой: проверьте mounts, сокеты, identity, egress и возможность выхода.
Происхождение контента делает решения проверяемыми. Прикрепляйте источник, автора, время получения, целостность и класс доверия к документу, описанию инструмента и его результату. Не теряйте эти сведения при суммировании и передаче другому агенту. Показывайте внешний контент как данные с явной меткой «не инструкция». Метка помогает модели, но права должен принуждать код. Удаляйте или канонизируйте невидимые символы на границах ввода и вывода, понимая, что видимые, кодированные и мультимодальные атаки останутся возможными.
Проверяйте вывод модели доверенным кодом: строгой схемой, allowlist инструментов, типизированными аргументами, проверкой URL и путей, лимитами размера и частоты и конечным автоматом сценария. Не превращайте мнение второй модели о безопасности в авторизацию. Критик может обнаружить подозрительный шаг, но финальное решение должно быть детерминированным. Записывайте промпт, источники, версию метаданных, аргументы, решения политики, подтверждения и ответ без исходных секретов.
Адаптивные оценки и эксплуатация
Оценивайте весь цикл агента, а не отдельный чатовый промпт. Нужны тесты прямого override, скрытого HTML, цитируемого письма, заражённого текста репозитория, вредного описания MCP, результата, требующего второго вызова, межсессионной памяти, многоязычных и кодированных строк, невидимых символов, SSRF-адресов метаданных, неверной аудитории токена и подмены операции после подтверждения. Добавляйте доброкачественные тексты, похожие на атаки, чтобы измерять ложные срабатывания и выполнение задачи.
Тестируйте адаптивно. Откройте red team ваши классификаторы, метки, схемы и правила подтверждения. Попросите менять формулировки, модальность, порядок инструментов, время и адреса данных. Статический benchmark может дать высокий результат, тогда как знающий защиту атакующий найдёт другой маршрут. Измеряйте успех атак, неразрешённые вызовы, байты, дошедшие до sink, повышение scopes, точность подтверждений, время обнаружения и отзыва доступа. После каждого изменения модели, промпта, сервера, политики или зависимости сохраняйте регрессионные тесты. В руководстве по оценке AI-агентов можно закрепить такой процесс.
Архитектуру сопоставляйте с production AI agent architecture. Детали OAuth описаны в MCP server TypeScript с OAuth.
Чек-лист инцидента
При подозрении на инъекцию остановите сценарий и отключите минимальную возможность, достаточную для сдерживания. Сохраните промпт, источник, происхождение, метаданные и версию инструмента, аргументы, метаданные токена без его значения, решения политики, подтверждения, адреса и время. Классифицируйте путь как прямой, косвенный, инструментальный или постоянный через память. Ищите тот же payload в других клиентах, индексах, очередях, логах и передачах между агентами.
Отзовите учётные данные, которые могли попасть в контекст или логи, завершите сессии и обновите refresh token. Заблокируйте адрес и пострадавший MCP-сервер. Проверьте внешние API на чтение, запись, сообщения и OAuth grants без разрешения. Сверьте выполненные аргументы с тем, что было показано и подтверждено.
После сдерживания удалите отравленные записи памяти и поиска, восстановите доверенные метаданные и добавьте путь атаки в регрессионные тесты. Зафиксируйте, что увидела модель, что разрешила политика, что одобрил человек и какой контроль не сработал. Подключите владельцев инцидента и приватности, если данные пересекли границу. Позднее распознавание текста классификатором не делает событие безопасным.
Чего защита не обещает
Prompt injection остаётся развивающейся задачей, потому что современные модели не проводят формальную границу между инструкциями и данными. Обучение, классификаторы, разделители, метки происхождения, схемы вывода и проверка человеком снижают риск, но адаптивный атакующий может изменить формулировку, кодировку, порядок и модальность. Человек ошибается из-за усталости или неполного preview. Sandbox бывает неверно настроен, а легитимный зафиксированный пакет может содержать вредный код.
Нельзя честно утверждать, что агент неуязвим. Можно утверждать, что у конкретного сценария есть явные границы доверия, минимальные возможности, детерминированные проверки, наблюдаемые решения, проверенные отказы и отработанная реакция. Пересматривайте это при добавлении MCP-сервера, инструмента, памяти, модели, источника данных или исходящего канала. Это инженерное руководство, а не сертификат и не аудит безопасности.
Источники
- OWASP GenAI LLM Top 10 2026
- Спецификация авторизации MCP
- Практики безопасности MCP
- OpenAI: Designing AI agents to resist prompt injection
- OpenAI: Understanding prompt injections
- Anthropic: Trustworthy agents in practice
- Google Cloud: AI security and safety for MCP servers
- Microsoft: Protecting against prompt injection attacks