Перейти к содержимому

Локальный файрвол stroq для кодинг-агентов: защита от prompt-инъекций и утечек секретов

Локальный файрвол действий для кодинг-агентов: как связать прочитанное с будущей командой

Кодинг-агент постоянно работает с данными, которым нельзя безоговорочно доверять. Он читает README библиотек, документацию, сообщения из issue-трекеров, ответы MCP-серверов, содержимое pull request и вывод команд, которые сам же запустил. Любой из этих каналов может содержать скрытую инструкцию: найти ключи, выполнить сетевой запрос, создать публичный репозиторий или запустить неизвестный скрипт.

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

Stroq - открытый локальный файрвол с лицензией Apache-2.0, созданный для контроля подобных сценариев. Он подключается к нативным хукам агента, анализирует прочитанный контент, помечает состояние сессии и проверяет следующее действие. Если команда связана с подозрительной инструкцией или нарушает политику, выполнение блокируется детерминированно. Для работы не требуются облачный сервис, внешний прокси или надежда на то, что языковая модель самостоятельно распознает инъекцию.

Почему обычных разрешений недостаточно

У большинства агентов есть механизм подтверждения опасных команд. На практике он не является полноценной границей безопасности. Пользователь быстро привыкает нажимать "разрешить", особенно если диалогов много, а команда выглядит знакомой.

К тому же стандартный классификатор может не видеть результаты инструментов. Если текст из README, MCP или вывода Bash не попадает в контекст механизма принятия решения, он не способен понять, что команда появилась под влиянием внешней инструкции. Получается разрыв: агент прочитал опасный текст, а система контроля видит только финальную строку команды.

Дополнительная проблема - контентная слепота самодельных хуков. Защиты, которые анализируют только PreToolUse, способны распознать `rm -rf` или подозрительный `curl`, но не понимают происхождение команды. Им неизвестно, была ли она частью задачи пользователя или появилась после обработки заражённого README.

Даже безопасная на вид команда может стать опасной в контексте. Например, `gh repo create --public --push` сама по себе выглядит как обычная операция разработчика. Но если перед ней агент прочитал инструкцию с указанием собрать `.env`, SSH-ключи и токены, эта же команда превращается в канал утечки.

Инциденты показывают общую закономерность

В одном из сценариев в issue-трекер помещалась якобы автоматически созданная рекомендация: запустить пакет через `npx` с параметром применения исправления. Агент получал текст через MCP и воспринимал его как результат инструмента, после чего запускал пакет атакующей стороны.

Другой пример связан с вредоносным пакетом Nx. Его postinstall-скрипт выводил в терминал текст, обращённый непосредственно к агенту: найти `.env`, каталог `.ssh` и npm-токены, сохранить найденные пути, а затем опубликовать данные через GitHub CLI.

В третьем случае вредоносные инструкции размещались в заголовках и комментариях pull request. Агент выполнял `ps auxeww`, извлекал значения переменных окружения и отправлял их обратно в комментарий. При этом несколько уровней стандартной защиты не распознали атаку.

Наконец, опасное поведение не всегда требует инъекции. Агент может самостоятельно решить, что для "очистки проекта" нужно удалить каталог в домашней директории. В другом известном сценарии команда принудительной публикации схемы привела к удалению производственной базы данных.

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

Архитектура Stroq

Файрвол работает через два основных этапа.

PostToolUse: анализ прочитанного

После завершения инструмента система получает его результат и нормализует содержимое. Обрабатываться могут ответы `Read`, `WebFetch`, `WebSearch`, `Bash`, `Grep`, а также инструменты с префиксом `mcp__`.

Нормализация не ограничивается переводом текста в единый регистр. Из потока удаляются zero-width-символы, tag-кодпоинты и variation selectors, учитываются варианты Unicode и маскировка команд через необычные пробелы или управляющие символы. Это необходимо, потому что злоумышленник может визуально скрыть инструкцию, разбить опасную строку невидимыми символами или использовать похожие знаки.

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

PreToolUse: проверка следующего действия

Перед запуском нового инструмента файрвол сопоставляет запрашиваемое действие с накопленным состоянием сессии. Если агент только что прочитал текст с указанием найти ключи и затем пытается выполнить `cat ~/.ssh/id_rsa`, это уже не обычная команда чтения файла. Она связана с ранее обнаруженной инструкцией и должна быть заблокирована.

Такой подход позволяет принимать решение не по одной строке, а по цепочке событий:

1. агент получил внешний текст;
2. в тексте обнаружилась инструкция;
3. агент сформировал действие, соответствующее этой инструкции;
4. действие нарушает установленную политику.

В результате контроль переносится с абстрактного "доверять ли модели" на наблюдаемую последовательность операций.

Три механизма, которых обычно не хватает

Provenance - происхождение инструкции

Система сохраняет информацию о том, откуда пришёл подозрительный фрагмент: файл, команда, веб-ответ, MCP-сервер, комментарий или вывод установочного скрипта. Это помогает отличить намерение пользователя от внешнего текста.

Secret egress guard

Отдельный уровень контролирует попытки вынести секреты за пределы рабочей среды. Проверяются обращения к `.env`, SSH-ключам, токенам npm, переменным окружения и другим чувствительным данным, а также команды, которые способны отправить их через Git, HTTP, GitHub CLI или иной сетевой инструмент.

Stroq attack

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

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

Почему важна детерминированность

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

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

Установка и практическая настройка

После установки Stroq его подключают к хукам агента. В конфигурации задаются правила для чтения файлов, запуска shell-команд, сетевого доступа, работы с Git и MCP-инструментами. Политику лучше начинать с режима аудита: сначала собирать события, проверять ложные срабатывания и только затем включать жёсткую блокировку.

Полезно разделять действия по уровням риска:

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

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

Честные ограничения

Файрвол не делает агент полностью безопасным. Он не способен гарантировать корректность бизнес-логики, обнаружить каждую социальную манипуляцию или понять, что безобидный на вид файл содержит критически важные данные. Возможны и ложные срабатывания: например, тест безопасности может намеренно обращаться к `.env` или имитировать публикацию секретов.

Кроме того, если злоумышленник уже получил контроль над самой системой, локальная защита может быть отключена или обойдена. Поэтому Stroq следует использовать вместе с минимальными правами, изолированными рабочими каталогами, защищёнными переменными окружения, отдельными токенами и резервным копированием.

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

Что можно улучшить дальше

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

Также полезны режимы "песочницы" для отдельных инструментов. Например, MCP-сервер может иметь доступ только к тестовым данным, а команды установки - выполняться в одноразовом контейнере без SSH-ключей и production-токенов.

Ещё одна важная функция - понятные объяснения блокировки. Пользователь должен видеть не просто отказ, а цепочку причины: "инструкция обнаружена в выводе внешнего инструмента", "после неё запрошено чтение секретного файла", "следующая команда отправляет данные в публичный репозиторий". Такой формат помогает быстро оценить ситуацию и не превращает защиту в раздражающий чёрный ящик.

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

Прокрутить вверх