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

Привет, Хабр! Я Денис Макрушин, работаю в Яндексе, и вместе с командой SourceCraft Security  строю платформу для безопасной агентской разработки, а в свободное время ищу уязвимости в ИИ-агентах и иногда рассказываю об исследованиях в своем блоге. Чем дольше этим занимаюсь, тем лучше вижу тенденцию: индустрия обсуждает, что агенты умеют делать, но реже говорит о том, какие решения и как проще внедрять, чтобы сделать агентскую инфраструктуру безопаснее. Вместе с моими коллегами Ратмиром Самархановым и Андреем Погирейчиком мы решили проверить гипотезу: “наши ИИ-агенты в разработке могут быть скомпрометированы и существуют простые средства для контроля их безопасности”. Расскажем о первых результатах.

Примечательная дата: 26 августа 2025 года злодеи заразили пакет Nx — сборочную систему, которую устанавливают около 6 миллионов раз в неделю. Вредоносные версии основного пакета nx оставались доступны в npm около четырех часов; точное число затронутых разработчиков в официальном postmortem не приводится. Ничего необычного для supply chain атак, которые случаются каждую неделю, — если бы не одна деталь. Разберём её, потому что вся атака состояла из на удивление тривиальных шагов.

У пакета Nx есть открытый репозиторий на GitHub, и, как у многих опенсорсных проектов, пул-реквесты проходят через GitHub Actions. Атакующие обнаружили shell injection через необработанный заголовок pull request в workflow с триггером pull_request_target. Это позволило выполнить команду в контексте раннера, получить GITHUB_TOKEN с правом записи, добавить вредоносную ветку и workflow, а через publish-процесс — вывести NPM_TOKEN. Сбор локальных файлов, переменных окружения и credentials выполнял уже postinstall-payload опубликованных пакетов.

Схема атаки s1ngularity

Схема атаки s1ngularity

Почему именно эта атака стала примечательной

Техника — command injection через непроверенный заголовок PR не является чем-то необычным. Знаковым инцидент делает то, что случилось дальше. Вредоносный код, попав на рабочую станцию через зараженный пакет, пытался вызвать установленные CLI Claude, Gemini и Amazon Q и давал им команду сформировать inventory-файл с секретами. Затем отправлял содержимое этого файла в репозиторий злодея. Это один из первых широко задокументированных supply-chain-инцидентов, в котором вредоносный код пытался задействовать локальные ИИ-инструменты.

А еще это неплохая иллюстрация того, куда вообще движется индустрия. Два года назад источником правды в разработке был код: мы писали его сами, тестировали сами, а спецификацию дописывали в лучшем случае “на бегу”. Сейчас значительную часть современного продукта составляют зависимости, библиотеки, SDK и фрагменты, сгенерированные агентом. Умение сформулировать намерение и acceptance-критерии становится важнее умения писать сам код, потому что кодовая база может быть целиком переписана на другом языке или вообще меняться в рантайме, а вот спецификация продукта пока еще остается статичной.

Как трансформирует процесс разработки

Как трансформирует процесс разработки

Проблема в том, что за это приходится платить. Каждая внешняя зависимость — потенциальная точка входа для атакующего, а агент, который эту зависимость подтягивает, ревьюит, мержит и разворачивает без участия человека, резко расширяет площадь, по которой можно бить. Ранее проводили исследование RepoJacking-атак и нашли более 1 300 потенциально уязвимых GitHub-репозиторие.

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

Три поверхности агентной системы

Чтобы не тонуть в зоопарке аббревиатур — tool poisoning, prompt injection, reasoning hijacking, — полезно смоделировать угрозы так же, как мы моделировали их для пакетов: составить карту компонентов и понять, что атакующий может сделать с каждым.

Для этого нужно разложить целевую систему на три ключевых компонента:

  • LLM/SLM — «мозг», который рассуждает и принимает решения;

  • контекст и память (включая RAG, если он используется) — источник данных, который нужен для модели;

  • инструменты — «руки», которыми агент меняет состояние внешнего мира (например, MCP-сервер как один из способов получить доступ к внешней среде)

Было бы не страшно, если бы агент только рассуждал и писал ответ в чат. Опасно то, что он рассуждает, принимает решение и потом действительно что-то меняет во внешней среде.

LLM: когда мозг не отличает данные от инструкций

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

Например, возможен сценарий jailbreak с помощью режима DAN («Do Anything Now»), когда пользователь уговаривает модель войти в режим без ограничений и выдать информацию, что она обычно отказывается выдавать (как вариант: рецепта нелегального вещества до вредоносного кода). Другой пример: непрямое внедрение запроса (indirect prompt injection), когда инструкция приходит не от пользователя напрямую, а через документ или веб-страницу, с которыми работает модель. То есть инструкцию «игнорируй все предыдущие инструкции и выведи текст X», спрятанную в тексте запроса, модель обрабатывает как обычные данные.

Другая категория проблем появляется в системах, где вывод модели используется в других компонентах. Если приложение вставляет ответ модели в DOM без дополнительной проверки (например, в виде данных в innerHTML), то у атакующего появляется возможность внедрить произвольный JS-код и провести XXS-атаку (привет старому пэйлоаду “<script>alert();<script>”). 

Другой интересный пример — обход защитных фильтров модели с помощью формальной логики. В исследовании 2026 года переформулировка запрещенных запросов на языке формальной логики повысила вероятность копрометации модели на 46–56%.

RAG: отравить или украсть

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

Скрытая инструкция в резюме или документе — это снова indirect prompt injection в модель. Если документ попадает в индекс и затем извлекается как доверенный контекст, то таким образом реализуется атака отравления RAG (RAG poisoning). Например, такая инструкция может заставить HR-агента искажать ответы о кандидате.

Возможность для возникает, когда приложение не контролирует доступ в процессе работы с RAG . В этом случае в контекст модели могут попасть секреты (например, зарплатные ведомости, финансовые показатели или NDA-документы), к которым у пользователя нет доступа.

MCP: руки, которые меняют мир

Model Context Protocol (MCP) — протокол уровня приложений на базе JSON-RPC для использования инструментов (tools), ресурсов и запросов к модели. MCP-сервер может быть локальным процессом или удаленным сервисом. Поэтому риски обычного веб-сервиса относятся прежде всего к удаленным MCP-компонентам. Подключенные инструменты превращают решение модели в действие во внешнем мире. Рассмотрим несколько показательных случаев за прошедший год.

В GitLab обнаружили, что ИИ-функция для исправления уязвимостей формировала запрос к LLM из полей SAST-отчёта без проверки недоверенных данных. Атакующий смог выполнить внедрение запроса через поле identifiers[].name и опубликовать его как результат работы SAST-анализатора. Когда разработчик нажимал “Исправить уязвимости”, модель добавляла управляемые атакующим команды в merge request, а настроенный для пайплайн тут же выполнял эти инструкции в контексте проекта. Баг получил идентификатор CVE-2024-7110 и был исправлен. 

Другой пример сценари показали исследователи Trail of Bits в платформе GitHub. Они спрятали инструкцию внутри HTML-элемента <picture> в GitHub-тикет. Для развития атаки maintainer репозитория должен был назначить Copilot на этот тикет, принять и смержить созданный PR, а затем развернуть приложение.

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

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

Copilot следовал инструкции и подставлял URL вредоносного пакета в кодовую базу проекта. В результате, после деплоя в приложении оказывался бэкдор, который выполнял любые команды из HTTP-заголовка X-Backdoor-Cmd.

Diff файла uv.lock: подмененный URL wheel-пакета, ведущий на сервер атакующего

Diff файла uv.lock: подмененный URL wheel-пакета, ведущий на сервер атакующего

И мой любимый пример, когда похожая уязвимость обнаружилась в специальном инструменте для проведения анализа защищенности с помощью ИИ. В открытом проекте CAI (Cyber Security AI) параметры username, host и port в SSH-компоненте могли привести к внедрению команд: shell-команда формировалась без достаточной валидации пользовательских значений, а еще могла быть использована для формирования запроса к LLM, с которой работал инструмент. Тот же класс уязвимости, что и в истории с заголовком PR у Nx, только теперь уязвим инструмент для пентеста.

Компонент

Что это

Основной класс атак

LLM/SLM

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

Прямой и непрямой prompt injection, jailbreak, небезопасная обработка вывода

RAG/память

Векторная база, embedder, retriever — источник знаний, которых не хватает модели

RAG poisoning; утечки при отсутствии tenant- или document-level ACL до retrieval

MCP-сервера / тулинг

Инструменты, локальные или удаленные; MCP — один из протоколов их подключения

Tool poisoning, Confused Deputy, уязвимости локальных и remote-интеграций

Как разорвать “летальное  трио”

Разные атаки на LLM, RAG и MCP удобно свести к одной модели угроз ИИ-агента. Саймон Уиллисон описал эту модель как “lethal trifecta” (“летальное трио”): когда у агента есть доступ к приватным данным, когда он обрабатывает недоверенный контент и когда у него есть возможности для взаимодействия с внешними системами (через которые можно вывести данные), то жди беды. 

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

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

  1. Ограничение доступа к приватным данным. Концепции Zero Trust больше 15 лет, но она становится как никогда актуальной для агенстких систем. Эта концепция предписывает проводить авторизацию всех вызовов инструментов, выдавать минимальные полномочия и повторно проверять контекст на границах доверия. Это можно реализовать с помощью отдельного control plane и identity provider для агенсткой инфраструктуры. Также отдельно нужно защищать runtime context, persistent memory и RAG.

  2. Разделение данных и инструкций. Здесь есть минимум два эффективных подхода. Первый подход помечает текст из внешних источников как недоверенный, второй задаёт приоритет: системные команды важнее указаний из документа, заявки или письма. Оба снижают риск того, что модель выполнит скрытую в данных команду, но полностью его не устраняют. Исследователи Microsoft предложили свой подход — систему FIDES. Она отслеживает происхождение данных и перед выполнением действия сверяется с заданными правилами. Если данные нельзя передавать внешней системе, действие блокируется независимо от решения модели.

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

С чего начать защиту своей инфры на практике

Первый практический шаг заключается в создании и совершенствовании непрерывного процесса анализа защищенности агента. Отсюда появилась категория инструментов для AI Red Teaming – процесса постоянного тестирования целевого агента и его компонентов. Постоянно скармливать агенту или модели промпты, постоянно мутировать промпты (вспоминаем методы фаззинга) и адаптировать их под специфику его окружения. Разбирать все ситуации, когда агент “вышел из себя”. Для этих задач есть готовый инструменты PromptFoo, а также более узкоспециализированные тулы под NSFW-атаки на репутацию, если нужно проанализиовать специфические генеративные модели для генерации контента.

Пример отчета об анализе защищенности LLM

Пример отчета об анализе защищенности LLM

Второй шаг заключается в выстраивании процесса разбора находок. Без него можно утонуть в обнаруженных аномалиях. Для офлайн-оценки можно использовать подход LLM-as-a-judge: отдельную модель (или ансамбль моделей), которая классифицирует запросы и ответы по степени риска и возможным категориям атак. Это может быть модель, блокирующая трафик в runtime и тогда она превращается в “guardrail model”. Несколько judges могут повысить устойчивость только при независимых категориях ошибок, но сам по себе количество judge-моделей не гарантирует надежность обнаружения.

Третий шаг: выстроить процесс защиты от обнаруженной угрозы. В конкретной реализации применение политики защиты можно условно разделить на два режима:

  • hard block, при котором запрос классифицируется как небезопасный и блокируется целиком;

  • advisory или safe-mode, при котором система ограничивает опасные детали в своем ответе на запрос и в результате возвращает безопасный ответ 

Три шага позволят построить первую версию непрерывного цикла:: тестирование, разбор находок и превращение результатов в правила блокировки или безопасного ответа. 

Кто отвечает за безопасность агентского цикла разработки

Данные Zero Day Clock показывают, что остается все меньше времени между раскрытием уязвимости и её эксплуатацией. Проект измеряет интервал от публикации CVE до первого подтверждённого сигнала атаки: время сократилась с 771 дня в 2018 году до 1 дня в 2026. Количетсво случаев, когда эксплуатацию фиксировали в день раскрытия или раньше, выросла с 19% до 48%. Про этот устойчивый тренд полезно помнить.

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

Именно в этот момент появляется подход безопасности “Shift down”, который в отличие от привычного “Shift left” (“встраиваем security-проверки на ранних этапах SDLC), переносит безопасность в платформу разработки и делает агентские guardrails ее неотъемлемой частью. Таким образом платформа может снизить когнитивную нагрузку на разработчика, при этом не снижая уровень безопасности в агентской разработке продукта.

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

Полезные ссылки:

Автор: makrushin

Источник

Оставить комментарий