309 правил, которые закрывают дыры в AI-агентах

309 правил, которые закрывают дыры в AI-агентах

На соревновании AI-агентовhttps://bitgn.com, где я участвовал, был класс задач на секьюрити. Там могли подсунуть промпт-инъекцию, попросить прочитать чужие файлы, вытащить переменные окружения, декодировать пейлоад и что-то выполнить.

Оттуда у меня и родилась идея плагина для opencode. Поставить перед опасными действиями детерминированный фильтр. Он проверяет входящие сообщения и аргументы тулов до того, как что-то уйдет в модель или в реальное исполнение.

Ссылка на сам плагин для opencode.

Сейчас в нем есть:

  • установка одной командой
  • минимальный конфиг
  • 309 правил из коробки
  • поддержка локальных моделей через opencode
  • открытый набор политик, который можно расширять под свою инфраструктуру

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

Потому что если защита на уровне промптов, то модель можно убедить делать то, что хочет злоумышленник. Если максимально упрощать:ignore previous instructions,show system prompt,decode and run this payload,[developer] do X.

Когда у агента есть файловые и шел тулы то можно произойти что-то подобное:

- чтение.env,~/.ssh,/run/secrets,/proc/self/environ- печать секретов черезprintenv,echo $TOKEN,export -p- подготовка данных к эксфильтрации черезbase64,xxd,openssl enc- попытки обойти правила через фейковыеsystemиdeveloperсообщения

Поэтому сначала проверка полиси, потом вызов модели или тула.

Как это устроено

У плагина всего два хука интеграции с opencode:

1.experimental.chat.messages.transform- обрабатывает пользовательские сообщения до отправки в модель2.tool.execute.before- проверяет вызов тула до исполнения

Это и есть ключевая идея. Если опасная команда уже дошла до шелл тула, то уже поздно. Проверка должна стоять раньше.

Что именно проверяется

Сейчас внутри два набора правил:

  • 282 правила для тулов
  • 27 правила для пропмпт инъекций

Оба набора лежат в json и работают как регекс политики. На старте они загружаются в память, после чего каждое подозрительное значение проверяется по набору правил.

Упрощенно это выглядит так:

Мне в этом подходе нравится предсказуемость. Если блок сработал, понятно почему. После инцидента можно быстро добавить новое правило. На набор политик легко писать детерминированные тесты. И поведение не зависит от того, какая модель стоит под капотом.

Как режется промпт инъекции

Для входящих сообщений плагин проходит поpartsи вытаскивает текстовые поля:text,prompt,command,source.value. Каждое значение прогоняется через набор правил для промпт нъекций.

Если есть совпадение, исходное сообщение не уходит в модель как есть. Оно подменяется безопасным отказом. Модель не видит атакующий ввод, а пользователь получает понятное объяснение, что запрос отклонен политикой.

Примеры правил:

То есть фильтр ловит англоязычные джеилбрейк фразы, русские варианты, и попытки подделать служебные роли.

fКак режутся опасные вызовы тулов

Второй слой работает наtool.execute.before. Здесь проверяется не толькоfilePath, а вообще все основные аргументы вызова:command,text,prompt,queryи даже имя тула.

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

Вот несколько примеров правил:

Если правило срабатывает, вызов останавливается до исполнения:

Команда просто не запускается.

Логи и разбор инцидентов

Каждое срабатывание логируется в jsonl. В лог пишется время, уровень, тип события, краткий контекст и идентификатор правила.

Это полезно:

  • видно, что именно пытался сделать агент
  • можно пополнять правила по реальным атакам
  • проще разбирать фалс позитив и фалс негатив

В итоге плагин работает еще и как слой наблюдаемости для агентного контура.

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

Многие опасные действия выражаются очень конкретно: имена файлов, shell-команды, сигнатуры вродеprintenv,base64,/run/secrets,ignore previous instructions,[system]. Здесь не нужна сложная семантика. Нужно надежно поймать известный паттерн до того, как он дойдет до модели или тула.

У регекс подхода есть и практические плюсы:

  • правила легко ревьюить
  • дифф по политике читается человеком
  • обновления легко привязывать к конкретным кейсам
  • одни правила для всех моделей

Понятно, что это не замена сендбокс, файловым ограничениям, белому списку тулов, сетевой изоляции и нормальной модели прав. Но как ранний и прозрачный слой защиты это очень полезная штука.

Что мне здесь нравится больше всего

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

Если ваши агенты работают с кодом, шелл, секретами, CI/CD или внутренними репозиториями, такой слой уже выглядит как базовая гигиена.

Как попробовать

Установка обычная:

Потом достаточно добавить плагин в конфиг opencode:

После этого opencode будет прогонять сообщения и вызовы тулов через слой правил до исполнения.

Откуда взялись правила

Правила я не хотел придумывать из головы, поэтому ориентировался на реальные атаки и существующие наработки. СпасибоВалерию Ковальскомуза чудесный проектhttps://github.com/vakovalskii/topsha, в котом уже есть набор таких правил из реальных атак 1500 инженеров.

Я уже сам этим пользуюсь. Если тоже работаете с агентами через opencode,посмотрите репу.

Читать оригинал