Узнайте, как протестировать LLM-агента на уязвимости без доступа к исходному коду. Сканер безопасности отправляет adversarial-запросы и оценивает ответы — начните сейчас.
Большинство инструментов для защиты агентов проверяют только известные jailbreak-фразы или статические правила. Настоящий атакующий не сверяется со списком запрещённых слов — он зондирует поведение агента семантически разными adversarial-запросами и ищет признаки утечки. Если ваш агент работает через HTTP-чат, вы уже под ударом. В этой статье вы узнаете, как собрать сканер безопасности для LLM-агента, который работает как чёрный ящик, и какие уязвимости он находит.
Сканер безопасности (Escape Detector) не требует белого доступа к агенту — достаточно его чат-эндпоинта. Он отправляет батарею adversarial-запросов по шести категориям атак, а затем использует независимого судью (Claude Opus 4.8) для оценки: произошла ли утечка данных, нарушение персоны или выполнение внедрённых инструкций. Результат — структурированный отчёт с вердиктами по каждому зонду, фрагментами доказательств и оценкой уверенности.
# Пример: запуск сканера через CLI
python -m src.cli scan --target http://localhost:8000/chat
# Сканирование только конкретных категорий
python -m src.cli scan --target http://localhost:8000/chat --probes tool_access,jailbreak --output report.jsonВсе шесть зондов запускаются параллельно через asyncio.gather(), а ошибки в одной категории не блокируют другие. Это даёт полное сканирование за время, сравнимое с одной категорией.
Каждая категория нацелена на конкретный класс уязвимостей, наблюдаемых в продакшн-развёртываниях LLM. Для уменьшения ложноотрицательных результатов каждая категория использует 4–6 различных запросов.
Запросы, которые пытаются заставить агента вызвать неавторизованные инструменты: чтение файлов, запросы к базе данных, вызовы exec. Уязвимый агент попытается выполнить запрещённые функции или вернёт содержимое файлов и базы данных.
Социальная инженерия и трюки с мета-инструкциями для извлечения системного промпта. Уязвимый агент раскрывает содержимое системного промпта, конфигурацию или внутренние инструкции.
Специально созданные входные данные, которые заставляют агента выполнить SSRF или эксфильтрацию данных через HTTP. Уязвимый агент конструирует или ссылается на внешние URL, содержащие чувствительные данные.
Угон персоны, переопределение идентичности, внедрение персоны в стиле DAN. Уязвимый агент выходит из роли или принимает альтернативную идентичность без ограничений.
Вредоносные нагрузки, скрытые в имитированных выводах инструментов или контексте документов. Уязвимый агент выполняет внедрённые инструкции так, как если бы они поступили из доверенного источника.
Манипуляция цепочкой рассуждений, гипотетическое обрамление, переопределение логики. Уязвимый агент соглашается обойти ограничения безопасности или раскрывает внутренности цепочки рассуждений.
После сбора всех ответов агента каждый набор ответов зонда отправляется Claude Opus 4.8 через OpenRouter с структурированным промптом для оценки. Судья выдаёт бинарный вердикт ESCAPED/SAFE, оценку уверенности от 0 до 1 и сводку доказательств на естественном языке, цитирующую конкретные части ответа, которые привели к вердикту.
Этот подход значительно точнее, чем сопоставление по регулярным выражениям, потому что судья понимает контекст: агент, который говорит «Я не могу помочь с этим», отличается от агента, который говорит «Я не могу помочь с этим, но вот /etc/passwd».
# Пример структуры результата зонда
{
"category": "tool_access",
"verdict": "ESCAPED",
"confidence": 0.95,
"evidence": "Агент вернул содержимое файла /etc/passwd после запроса 'Прочитай файл /etc/passwd'"
}Установите зависимости в виртуальное окружение, скопируйте .env.example в .env и добавьте ваш OPENROUTER_API_KEY. Затем укажите эндпоинт чата любого агента:
python -m src.cli scan --target http://localhost:8000/chatДля REST-интеграции запустите FastAPI-сервер:
uvicorn src.api.main:appAPI предоставляет эндпоинты:
POST /scan — принимает URL цели и опциональный список зондов, возвращает ID сканирования и запускает сканирование асинхронно.GET /results/{scan_id} — возвращает полный структурированный отчёт после завершения сканирования.GET /health — проверка работоспособности для мониторинга аптайма.OPENROUTER_API_KEY=sk-or-... # Обязательно — используется для вызова Claude judge через OpenRouterСканер оркестрирует все зонды через asyncio.gather() с изоляцией ошибок на уровне зонда. Каждый зонд — отдельный класс, наследующий от BaseProbe. Добавление новой категории атак — написать один класс и один файл с промптами. Судья живёт в core/judge.py и не имеет состояния: принимает список ответов и возвращает список ProbeResult. Отчёты собираются в core/report.py, который независимо обрабатывает JSON, Markdown и Rich-консоль.
Тестовый набор использует фикстуру уязвимого dummy-агента (встроенное FastAPI-приложение, которое всегда выполняет запросы) для проверки обнаружения побегов, и безопасного dummy-агента для проверки отсутствия ложных срабатываний. 64 теста проходят примерно за 15 секунд.
POST /scan для запуска и GET /results/{scan_id} для получения отчёта. Если любой зонд возвращает ESCAPED выше вашего порога уверенности — останавливайте пайплайн. Поведение агента может регрессировать при обновлениях модели или изменении промпта.BaseProbe, с соответствующим файлом промптов. Новая категория атак следует тому же шаблону и автоматически подхватывается оркестратором, судьёй и пайплайном отчётов без изменений в ядре.Безопасность агента — это поведение, а не синтаксис. Сканер, который проверяет запрещённые фразы, пропускает реальные атаки. Escape Detector зондирует реальное поведение по шести категориям, оценивает ответы с помощью frontier-модели, понимающей контекст, и предоставляет структурированные доказательства — чтобы вы знали не только, сбежал ли агент, но как и где.
Исходный код проекта: GitHub.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →