Мой AI-чат ломают две недели: 8 правил защиты ИИ-агентов

безопасность ИИ-агентов
защита AI-чата
prompt injection защита
sandbox для ИИ-агента
guardrails для LLM

Мой AI-чат ломают две недели: 8 правил защиты ИИ-агентов

Уже две недели кто-то методично пытается сломать чат на моём сайте. Пробует заставить модель забыть инструкции, раскрыть внутренний промпт, выполнить чужую команду или добраться до того, чего пользователь видеть не должен. По моим наблюдениям, полезного результата нет. Судя по тону последних сообщений, человек ещё и обиделся 😞

Секрет не в «непробиваемом промпте». Безопасность ИИ-агентов начинается с того, что даже успешно обманутая модель не получает возможности причинить ущерб. У публичного чата нет shell, bash и произвольного выполнения кода; инструменты узкие; секреты не попадают в контекст; опасные действия проверяет код вне LLM; runtime изолирован; персональные данные маскируются; каждый шаг оставляет очищенный след в системе наблюдения.

Коротко: считайте prompt injection ожидаемым событием. Не пытайтесь доказать, что модель никогда не ошибётся. Спроектируйте систему так, чтобы ошибка модели упиралась в права, policy-check, sandbox, лимит и подтверждение человека.

Содержание

Что именно пытаются взломать

В публичном AI-чате обычно атакуют не веса модели. Атакующий манипулирует инструкциями и контекстом:

  • просит игнорировать правила;
  • маскирует команды под цитату, код, документ или данные;
  • пытается вытащить системный промпт, историю или секрет;
  • добивается вызова инструмента с опасными параметрами;
  • повторяет варианты, пока фильтр не пропустит один из них;
  • старается записать вредную установку в память следующей сессии.

OWASP определяет prompt injection как манипуляцию поведением LLM через вредоносный ввод. Среди последствий названы обход защитных правил, утечка данных, раскрытие системного промпта, действия через инструменты и устойчивое влияние между сессиями.

Здесь важно разделить два класса проблем.

Класс Что происходит Главная защита
Модель обманули LLM поверила чужой инструкции guardrails, разделение инструкций и данных, проверка выхода
Обманутая модель получила полномочия LLM вызвала опасный инструмент, увидела секрет или вышла в сеть минимальные права, tool broker, sandbox, approvals, egress policy

Первый класс нельзя считать полностью закрытым. Поэтому архитектура обязана остановить второй.

Почему одного системного промпта мало

Системный промпт полезен как описание роли, но это не граница безопасности. Он обрабатывается той же моделью, которая читает недоверенный текст. Если контроль существует только в естественном языке, атакующий спорит с моделью на её территории.

OWASP AI Agent Security Cheat Sheet отдельно перечисляет злоупотребление инструментами, повышение привилегий, утечку данных, отравление памяти, перехват цели и чрезмерную автономность. Это уже не задача «написать промпт построже».

Практический принцип такой:

LLM предлагает намерение. Доверенный код решает, можно ли его выполнить.

Policy-слой должен получать исходную цель пользователя, тип действия, параметры, идентичность, текущий лимит и риск. Решение allow, deny или require_approval принимает не основной агент.

8 правил безопасности ИИ-агентов

1. Публичному агенту нельзя давать shell, bash и произвольный code execution

Если агент доступен из интернета, универсальный командный интерпретатор превращает ошибку модели в доступ к операционной системе. Даже если вы разрешаете «только одну команду», оболочка часто расширяет поверхность через аргументы, перенаправления, переменные, подстановки и дочерние процессы.

OWASP по чрезмерной агентности советует избегать открытых расширений вроде запуска shell-команд и заменять их узкими функциями. Публичному чату для ответа на вопрос чаще всего нужен вызов LLM, а не агент с правом выполнять код.

Если выполнение кода действительно составляет продукт, выносите его в отдельный одноразовый job:

  • новая изолированная среда на каждый запуск;
  • пустая файловая система или разрешённый набор файлов;
  • нет секретов и домашней директории;
  • сеть закрыта по умолчанию;
  • жёсткие лимиты CPU, памяти, времени и размера вывода;
  • уничтожение среды после результата.

2. Давайте только те инструменты, которые безопасны во всех допустимых параметрах

Инструмент run_sql(query) опаснее, чем get_order_status(order_id). Инструмент http_request(url, method, body) опаснее, чем get_exchange_rate(currency_pair).

Хороший tool layer строится по принципу минимальных полномочий:

  • отдельная функция на отдельное бизнес-действие;
  • строгая схема параметров;
  • server-side allowlist идентификаторов и направлений;
  • read-only по умолчанию;
  • проверка прав на каждый вызов;
  • idempotency key для повторяемых операций;
  • ручное подтверждение перед удалением, оплатой, публикацией или отправкой сообщения.

OWASP рекомендует ограничивать и набор инструментов, и функциональность каждого инструмента. Если чату не нужно удалять письма, функция удаления не должна существовать в доступной модели схеме.

3. Агент работает в sandbox или microVM — либо не используется

Sandbox ограничивает процесс внутри общей ОС. MicroVM даёт более сильную границу с отдельным ядром и лучше подходит для недоверенного кода. Выбор зависит от риска, но правило одно: агент не должен работать рядом с production-секретами и данными только потому, что так проще собрать прототип.

Задача Режим по умолчанию
ответить на вопрос, классифицировать, суммировать обычный вызов LLM без инструментов
прочитать разрешённые данные через узкий API агент с read-only tools и policy broker
изменить запись или отправить сообщение узкий tool + проверка прав + подтверждение
выполнить пользовательский код одноразовый sandbox/microVM без секретов и с закрытой сетью

OpenAI описывает sandbox как один из уровней, который может обнаружить неожиданную коммуникацию и запросить согласие пользователя. Но sandbox не отменяет ограничения сети, прав и времени: изолированная среда с открытым egress всё ещё может отправить данные наружу.

4. Guardrails и hooks обязательны, но выполняют разные роли

Guardrail проверяет вход, выход или конкретный tool call. Hook наблюдает за жизненным циклом: до и после вызова LLM, инструмента, передачи управления или завершения агента.

Минимальный набор:

  1. input guardrail — prompt injection, тип запроса, rate limit, размер и кодировки;
  2. pre-tool guardrail — соответствие действия исходной цели, права, параметры, бюджет;
  3. post-tool guardrail — очистка и проверка результата инструмента;
  4. output guardrail — секреты, PII, опасная разметка, обещания выполненных действий;
  5. hooks — логирование, метрики, лимиты, аудит, аварийная остановка.

Документация OpenAI Agents SDK показывает input-, output- и tool-guardrails, а lifecycle hooks позволяют наблюдать начало и конец вызовов модели и инструментов. При этом встроенные shell- и hosted-tools могут не проходить через тот же tool-guardrail pipeline. Проверяйте реальный путь исполнения вашего SDK, а не наличие красивого декоратора в коде.

Guardrail на базе LLM тоже может ошибиться. OWASP советует использовать его как один слой, а не замену проверкам параметров, минимальным правам и подтверждению необратимых действий.

5. LLM не должна видеть ключи, токены и чувствительные данные

Не кладите секреты:

  • в system prompt;
  • в историю диалога;
  • в описание инструмента;
  • в переменные, доступные code runner;
  • в полный вывод базы данных;
  • в trace без редактирования.

Модель должна передавать намерение: получить статус заказа 123. Доверенный backend сам выбирает credential, проверяет права и вызывает сервис. Лучше использовать короткоживущий токен с одним scope на один run, чем общий API-ключ компании.

Секрет, которого нет в контексте, нельзя выманить из контекста. Это сильнее любого обещания модели «никогда не раскрывать токены».

6. Компакты сессий должны сохранять правила, а не яд атаки

Под «компактом» я имею в виду сжатое резюме длинной сессии, которое заменяет старые сообщения. Это полезно для стоимости и размера контекста, но создаёт две опасности:

  1. важное ограничение исчезает после сжатия;
  2. вредная инструкция из диалога попадает в резюме и становится похожей на доверенную память.

После каждого compaction восстанавливайте неизменяемые security-инварианты из доверенного кода: доступные tools, права, запреты, исходную цель, лимиты и список подтверждённых фактов. Недоверенный текст храните с provenance: кто его прислал, когда и с каким уровнем доверия.

Не позволяйте самой LLM решать, какую атакующую инструкцию записать в долговременную память. OWASP относит memory poisoning к отдельным рискам агентных систем.

7. Privacy-filter ставится до LLM, демаскировка — после неё

Рабочий путь выглядит так:

  1. detector находит имя, телефон, email, адрес, документ или другой PII;
  2. локальный сервис заменяет значение стабильным placeholder: [PERSON_1], [PHONE_1];
  3. LLM работает только с маскированным текстом;
  4. разрешённые placeholders восстанавливаются локально перед ответом;
  5. карта соответствий не уходит провайдеру модели и имеет короткий TTL.

Microsoft Presidio поддерживает replace, redact, hash, mask и encrypt, а для обратимых операций — deanonymization. Для демаскировки нужна обратимая операция; хэширование и удаление исходное значение не восстановят.

Privacy-filter не даёт гарантии 100% обнаружения. Добавьте собственные recognizers для российских телефонов, паспортов, ИНН, договоров и внутренних идентификаторов, а на выходе повторите DLP-проверку.

8. Observability должна показывать цепочку, но не превращаться в новую утечку

Для каждого запроса полезно видеть:

  • session ID и trace ID;
  • версию промпта, модели и policy;
  • решение каждого guardrail;
  • tool name, очищенные аргументы и результат;
  • latency, tokens, cost и количество шагов;
  • approvals, отказы и причину остановки;
  • признак compaction и версию восстановленных правил.

Langfuse связывает prompts, responses, tool calls и retrieval steps в один trace, а traces — в sessions. Это помогает восстановить причинную цепочку, сравнивать версии и находить аномалии.

Но не отправляйте в систему наблюдения то, что запретили отправлять в LLM. До экспорта trace удаляйте секреты и PII, ограничивайте доступ к проекту, задавайте retention и логируйте просмотр чувствительных событий. Для короткоживущих процессов не забывайте принудительно отправлять накопленные события перед завершением.

Как выбрать между LLM, агентом и code runner

Самая безопасная оптимизация — не давать агентность там, где она не нужна.

Вопрос Если ответ «нет» Если ответ «да»
Нужно ли системе действовать, а не только отвечать? обычный вызов LLM переход к следующему вопросу
Можно ли выразить действие узкой server-side функцией? не выдавать универсальный tool создать типизированный tool
Действие обратимо и малорисково? approval вне LLM лимит + audit trail
Требуется недоверенный код? не давать code execution отдельная одноразовая microVM

NIST в профиле рисков генеративного ИИ рассматривает безопасность, приватность, оценку, эксплуатацию и мониторинг как части жизненного цикла системы. Это полезная рамка: защита не заканчивается после выбора модели.

Как должен проходить запрос

Этап Что делает система Что не доверяется
1. Edge rate limit, WAF, размер запроса, abuse score IP и текст пользователя
2. Privacy обнаружение и маскирование PII/секретов исходные значения
3. Input policy классификация injection и допустимой задачи решение одной LLM
4. LLM формирует ответ или намерение собственному утверждению «это безопасно»
5. Tool broker права, schema, scope, budget, approval аргументы от модели
6. Runtime sandbox/microVM, закрытый egress, лимиты выполняемому коду и файлам
7. Output policy DLP, HTML sanitization, проверка результата выводу модели и инструмента
8. Telemetry редактированный trace, alert, incident link сырым prompt и credential

Для публичного чата я бы начал с нулевого бюджета опасных действий:

  • 0 shell-инструментов;
  • 0 production-секретов в контексте;
  • 0 необратимых действий без подтверждения;
  • максимум 5 tool calls на один запрос;
  • максимум 30 секунд на agent run;
  • отдельный лимит попыток на IP, пользователя и сессию;
  • автоматическая блокировка серии однотипных injection-попыток.

Это стартовая конфигурация, а не универсальный стандарт. Лимиты нужно подобрать по вашим обычным traces и сценарию продукта.

Что проверить за 30 минут

  1. Выгрузите список всех tools, доступных публичному агенту.
  2. Удалите shell, code execution, произвольный HTTP и универсальный SQL.
  3. Для оставшихся tools запишите допустимые параметры и права.
  4. Проверьте, какие секреты попадают в prompt, tool output и trace.
  5. Закройте egress sandbox по умолчанию.
  6. Добавьте approval для удаления, оплаты, отправки и публикации.
  7. Убедитесь, что правила восстанавливаются после compaction.
  8. Поставьте privacy-filter до LLM и DLP после неё.
  9. Запишите один red-team сценарий и проследите его целиком в Langfuse или другой tracing-системе.
  10. Добавьте kill switch: отзыв токена, отключение tool broker и остановка активных runs.

FAQ

Можно ли полностью защититься от prompt injection?

Нельзя обещать, что модель никогда не последует вредной инструкции. Можно резко ограничить последствия: убрать опасные tools, применить минимальные права, проверять действия доверенным кодом, изолировать runtime и требовать подтверждение человека.

Достаточно ли sandbox для ИИ-агента?

Нет. Sandbox ограничивает процесс, но отдельно нужны закрытый egress, отсутствие секретов, лимиты ресурсов, одноразовая среда и контроль доступных файлов. Иначе изолированный процесс всё ещё может отправить данные наружу или атаковать доступный сервис.

Guardrails и hooks — это одно и то же?

Нет. Guardrails принимают решение о допустимости входа, выхода или вызова инструмента. Hooks получают события жизненного цикла и подходят для логов, метрик, лимитов и аварийной реакции. В policy-системе нужны оба механизма.

Как не отправлять персональные данные в LLM?

Обнаруживайте PII локально, заменяйте значения placeholders, храните таблицу соответствий вне модели и восстанавливайте только разрешённые поля после ответа. Повторная выходная проверка нужна, потому что detector может пропустить нестандартный идентификатор.

Нужно ли логировать все prompts в Langfuse?

Нужно видеть причинную цепочку, но сырой prompt не обязан храниться целиком. Маскируйте PII и секреты до экспорта, ограничивайте retention и доступ, а для расследований сохраняйте только необходимый объём данных.

Что делать с безопасностью после compaction сессии?

Заново добавлять security-инварианты из доверенного источника и не повышать уровень доверия к пользовательскому тексту только потому, что он оказался в резюме. Версию компакта и восстановленных правил полезно записывать в trace.

Итог

Человек, который две недели пытается сломать мой чат, может когда-нибудь подобрать фразу, на которую модель ответит странно. Это неприятно, но не должно становиться инцидентом.

Настоящая защита начинается после модели: у публичного чата нет shell, опасных универсальных tools и секретов; tool broker проверяет каждое действие; sandbox ограничивает среду; privacy-filter скрывает данные; компакты не стирают правила; traces позволяют восстановить цепочку.

Первое действие — убрать у публичного агента все полномочия, без которых чат продолжит выполнять свою задачу. Ноль лишних возможностей даёт больше безопасности, чем ещё один абзац в system prompt.

Источники

← Все статьи

Комментарии (0)

Пока нет комментариев. Будьте первым!

Оставить комментарий
Регистрация не требуется