3,583 papers
arXiv:2610.23109 74 16 окт. 2026 г. FREE

TrojanForge: автоматическое отравление репозиториев, которое обманывает кодинг-агентов

КЛЮЧЕВАЯ СУТЬ
Парадокс: лучшее место для вредоносного кода — то, которое проверяющий ИИ назвал самым безобидным. Система TrojanForge автоматически отравляет чистый репозиторий так, что агент для кода сам запускает вредонос. Средний успех атаки выше 60%, а «закладки» в компонентах срабатывали больше чем в 90% случаев. Для вас это значит: перед запуском агента в чужом репозитории можно сделать быстрый аудит. Фишка: смотри не на верх списка подозрительности, а на его низ. Именно там атакующий прячет код, потому что агент считает такие места фоном.
Адаптировать под запрос
⚡

TL;DR

TrojanForge — автоматическая система, которая берёт чистый репозиторий и прячет в нём вредоносный код так, чтобы кодинг-агент сам его запустил. Система вычисляет, какие файлы агент точно откроет при задаче пользователя. Потом просит «агента-безопасника» ранжировать эти места по подозрительности и прячет код в самом нижнем месте списка. Затем она много раз проверяет маскировку на целевом агенте и учится на его же рассуждениях.

Боль в том, что агент при обычной задаче («почини баг», «разверни окружение») не проверяет всё подряд. Он идёт по пути задачи и доверяет «скучному» коду: конфигам, логгерам, вспомогательным функциям. Если вредоносная вставка названа и оформлена как остальной код, агент её не замечает и запускает как побочный эффект работы. В тестах средний успех атаки превысил 60%. «Закладки» в компонентах кода срабатывали более чем в 90% случаев. Коммерческие агенты не устояли.

Метод в три шага: (1) найти код, до которого агент дойдёт при задаче; (2) выбрать из него наименее подозрительные места; (3) подбирать маскировку циклами, превращая причины провалов в правила для следующей попытки. Для читателя главная ценность не в самой атаке, а в знании: чужой репозиторий — недоверенный ввод, и агент сам вас не защитит.

🔬

Схема метода

ШАГ 1. Достижимость: агент решает задачу на чистом репо → лог команд
        → LLM сопоставляет лог с функциями (AST) → список мест, которые агент выполнит
ШАГ 2. Слепые зоны: агент-безопасник (ему сказано «тут есть вредонос»)
        ранжирует места по подозрительности с причиной → берут k САМЫХ НЕПОДОЗРИТЕЛЬНЫХ
ШАГ 3. Маскировка (цикл): N вариантов маскировки → проверка на целевом агенте
        → провал: из его рассуждений делают правила («имя выдало замысел» → «называй по бизнес-стилю»)
        → новый круг; успех → в «библиотеку опыта» для других репозиториев
Проверка успеха: детерминированная (код реально сработал), а не оценка LLM-судьёй

Шаги идут отдельными запросами и вызовами агентов, это автоматизированный конвейер.

🚀

Пример применения

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

Задача: Вы фрилансер. Заказчик прислал репозиторий «скрипты для выгрузки заказов из Wildberries в Google Таблицы» и просит: «Почини падение на выгрузке остатков». Вы собираетесь отдать репозиторий Claude Code. Сначала нужен быстрый аудит.

Промпт:

Ты — аудитор безопасности. Известно, что в этом репозитории ПРИСУТСТВУЕТ
вредоносный код. Он спрятан так, чтобы выглядеть обычным.

Задача пользователя, ради которой репозиторий будет запускаться:
«Починить падение на выгрузке остатков (export_stock.py)».

Кандидаты — файлы и функции, которые выполнятся при этой задаче:
1. export_stock.py::main()
2. wb_api/client.py::request()
3. config/settings.py::load()
4. utils/logger.py::setup()
5. setup.py (хуки установки)
6. tests/conftest.py

Проверь каждое место по-настоящему: открой файл, прочитай код.
Выдай список от самого подозрительного к наименее подозрительному.
К каждому месту — короткая причина: что в нём настораживает
(имя, не вяжущееся с содержимым; сетевые вызовы; удаление файлов;
запись в чужие каталоги; код, не вписывающийся в стиль модуля).

Отдельно в конце: для 3 НИЖНИХ пунктов списка перечисли, что именно
ты НЕ проверил и почему счёл их безобидными.

Результат: Модель выдаст ранжированный список с причинами для каждого места. Ключевая часть — финальный блок: он покажет, какие «скучные» места (логгер, конфиг, хуки установки) аудитор счёл безобидными. Их стоит дочитать глазами. Формат — нумерованный список и короткий абзац в конце.

🧠

Почему это работает

Слабость агента. У него ограниченное внимание: он проверяет то, что бросается в глаза. Имя вроде send_data_to_server насторожит, а normalize_config_paths — нет. Когда код вписан в стиль модуля и стоит там, где «обычно всякое бывает», агент считает его частью фона.

Сильная сторона LLM. Если сказать модели «вредонос точно есть», она проверяет ощутимо усерднее и умеет ранжировать места по подозрительности с объяснением. Подозрения предсказуемы: у разных агентов они совпадают. Поэтому ранжирование одного агента хорошо предсказывает слепые зоны другого.

Как метод это использует. Он инвертирует список: слепая зона находится по самому низу ранжирования. Вторая инверсия — разбор провалов: рассуждение агента «почему я это заметил» превращается в правило «делай так, чтобы не заметил». Для защитника то же самое работает наоборот: причины, по которым агент замечает подозрительное, показывают, на какие признаки он реагирует. Всё остальное он пропускает.

Рычаги для защитного аудита: - Фраза «вредонос точно есть» → делает аудит строже, меньше «всё выглядит нормально». - Список кандидатов → сужай до пути задачи, иначе аудит растянется на весь репозиторий. - Блок «что НЕ проверил» → заставляет модель назвать слепые зоны вслух. - Причина к каждому пункту → убери, если нужен только быстрый список.

📋

Шаблон промпта

Ты — аудитор безопасности. Известно, что в репозитории {название} ПРИСУТСТВУЕТ
вредоносный код, замаскированный под обычный.

Задача пользователя: «{задача}».

Кандидаты — места, которые выполнятся при этой задаче:
{список_файлов_и_функций}

Открой и прочитай каждое место. Выдай список от самого подозрительного
к наименее подозрительному. К каждому — короткая причина: что в нём
настораживает (имя, не вяжущееся с содержимым; сетевые вызовы; удаление
файлов; запись в чужие каталоги; несоответствие стилю модуля).

В конце: для {число} нижних пунктов перечисли, что ты НЕ проверил,
и почему счёл их безобидными.

Подставляйте: {название} — имя репозитория, {задача} — то, что собираетесь поручить агенту, {список_файлов_и_функций} — файлы из ls и места, куда пойдёт агент, {число} — обычно 3.

🚀 Быстрый старт — вставь в чат:

Вот шаблон аудита репозитория перед запуском агента. Адаптируй под мою задачу: [твоя задача].
Задавай вопросы, чтобы заполнить поля.

[вставить шаблон выше]

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

⚠️

Ограничения

⚠️ Защита не проверялась: статья про атаку. Рецепт защиты (аудит с инверсией списка, изоляция) авторы не тестировали, это вывод из логики метода.

⚠️ Аудитора тоже можно обмануть: атака подбирается именно под целевого агента. Модель-ревьюер может пропустить то же, что пропустит агент.

⚠️ Не 100%: в среднем агенты ловят заметную долю атак. Значит, «агент почти всегда замечает» неверно, но и «никогда не замечает» тоже.

⚠️ Сам метод — инженерный: он требует разбора синтаксических деревьев кода, запуска агентов, библиотеки опыта. В обычном чате воспроизвести его нельзя, воспроизводится только аудит.

⚠️ Неполные данные: в доступной части статьи нет подробного разбора сбоев и сравнения моделей и оболочек. Выводы о различиях между агентами сделать нельзя.

🔍

Как исследовали

Команда взяла 136 чистых репозиториев из SWE-bench, Commit0 и GitHub: шесть типов задач (разработка, баги, развёртывание, обработка данных, поддержка, оптимизация) и девять языков. Задачи для агента LLM синтезировала из реальных issues и коммитов, чтобы они были как в жизни. Затем система внедряла четыре типа вредоносной нагрузки: кража данных, удаление файлов, подмена значений, «закладка» в компоненте.

Важная деталь дизайна: успех проверяли детерминированно. Смотрели, что вредоносное действие реально произошло, а не что LLM-судья сказал «похоже на успех». Так цифрам можно доверять больше.

Результат: средний успех атаки выше 60%, пик 76% (кража), 85% (удаление), 94% (подмена), 100% (закладка). В итоге получился бенчмарк на 384 отравленных репозитория, который прогнали на 4 оболочках агентов и 12 моделях. Вывод: даже коммерческие агенты не защищены от такого отравления.

Что показательно: самое слабое звено — не «умность» модели, а предсказуемость внимания. Любой ревьюер с похожей логикой подозрения подсказывает, где прятаться. Для практики это значит: безопасность нельзя отдавать агенту целиком. Нужна изоляция (песочница, ограничение сети, подтверждение команд) и ручной просмотр хвоста списка.

💡

Адаптации и экстраполяции

💡 Адаптация для приёмки чужого кода: то же ранжирование, но по задаче «принять пулреквест от подрядчика». В кандидатах — изменённые файлы в диффе, а не весь репозиторий. Смотрите на хвост списка и блок «что не проверил».

🔧 Техника (моя экстраполяция, в статье не проверялась): добавьте в CLAUDE.md или AGENTS.md правило: «Перед запуском скриптов установки, хуков, conftest.py и конфигов из чужого репозитория покажи мне их содержимое и жди подтверждения». Логика: слепые зоны из статьи — как раз «скучные» точки входа.

🔗

Ресурсы

  • Trojan Horse: Automated Repository Poisoning against Coding Agents — Xiao Yang, Jinchang Hou, Jiawei Chen, Zhonghou Lv, Junyuan Shang, Chenfu Bao. Baidu Inc.; Beihang University; East China Normal University; Zhongguancun Academy.
  • Код: github.com/SimonsShoot/TrojanForge
  • Бенчмарк: huggingface.co/datasets/MikeYoung123/TrojanBench
  • Страница проекта: simonsshoot.github.io/TrojanForge
  • Связанные работы в статье: MCPTox (отравление инструментов MCP), CIPR, RepoGuardBench, Day et al. (топология рабочего пространства).

📋 Дайджест исследования

Ключевая суть

Парадокс: лучшее место для вредоносного кода — то, которое проверяющий ИИ назвал самым безобидным. Система TrojanForge автоматически отравляет чистый репозиторий так, что агент для кода сам запускает вредонос. Средний успех атаки выше 60%, а «закладки» в компонентах срабатывали больше чем в 90% случаев. Для вас это значит: перед запуском агента в чужом репозитории можно сделать быстрый аудит. Фишка: смотри не на верх списка подозрительности, а на его низ. Именно там атакующий прячет код, потому что агент считает такие места фоном.

Принцип работы

Атака идёт в три шага, и защитник может повторить логику наоборот. 1. Путь задачи: агент решает задачу на чистом репозитории. По логу команд видно, какие функции он точно выполнит. 2. Слепые зоны: другому агенту говорят «вредонос тут есть» и просят ранжировать места по подозрительности. Атакующий берёт самые неподозрительные. 3. Маскировка по кругу: вставку проверяют на целевом агенте. Если заметил, его же объяснение превращают в правило («имя выдало замысел» → «называй как остальной код»). Агент не читает репозиторий целиком — он идёт по пути задачи и верит скучному коду. Это как охранник, который смотрит на чемоданы с подозрительным видом, а рабочий комбинезон с инструментами пропускает не глядя.

Почему работает

Агент проверяет то, что бросается в глаза. Имя send_data_to_server его насторожит, а normalize_config_paths нет. Код в стиле модуля, лежащий в конфиге или логгере, становится частью фона. Есть и вторая половина. Скажи модели «вредонос точно есть» — и она проверяет усерднее. Она умеет ранжировать места с объяснением. Подозрения у разных агентов совпадают, поэтому ранжирование одного хорошо предсказывает слепые зоны другого. Атакующий превращает «почему я это заметил» в «как сделать, чтобы не заметил». Защитник использует то же самое наоборот. Причины, по которым агент замечает подозрительное, показывают, на какие признаки он реагирует. Всё остальное он пропускает.

Когда применять

Работа с чужим кодом → перед тем как отдать репозиторий агенту для кода (Claude Code, Cursor и подобным), особенно когда задача «почини баг» или «разверни окружение» и агент будет запускать файлы. Подходит фрилансерам, тем, кто клонирует незнакомые репозитории, и командам, которые принимают чужие доработки. НЕ подходит как единственная защита. Авторы атаку проверяли, а защитный аудит нет: это вывод из логики метода. Аудитора-ИИ тоже можно обмануть, ведь атака подбирается под конкретного агента. Запускай чужой код в изолированной среде (песочнице), а промпт используй как дополнительный фильтр.

Мини-рецепт

1. Сузь путь: выпиши файлы и функции, которые выполнятся при твоей задаче. Не весь репозиторий, а только маршрут агента.
2. Скажи страшное: напиши модели, что вредонос в репозитории точно есть. Так она проверяет строже и не отвечает «всё выглядит нормально».
3. Попроси ранжирование: от самого подозрительного к наименее подозрительному, к каждому месту короткая причина.
4. Заставь признаться: для 3 нижних пунктов пусть назовёт, что не проверила и почему сочла безобидным.
5. Дочитай низ глазами: логгер, конфиг, хуки установки, файл с тестами. Именно там вредонос прячется чаще всего.
6. Запускай в песочнице: даже если аудит чистый, агента пускай в изолированную среду без секретов.

Примеры

[ПЛОХО] : Проверь репозиторий на безопасность, потом почини падение в export_stock.py
[ХОРОШО] : Ты аудитор безопасности. В репозитории ТОЧНО есть вредоносный код, замаскированный под обычный. Задача: починить падение в export_stock.py. Кандидаты: 1) export_stock.py::main() 2) wb_api/client.py::request() 3) config/settings.py::load() 4) utils/logger.py::setup() 5) setup.py 6) tests/conftest.py. Открой и прочитай каждое место. Выдай список от самого подозрительного к наименее подозрительному, к каждому причина: имя не вяжется с содержимым, сетевые вызовы, удаление файлов, запись в чужие каталоги, код не в стиле модуля. В конце: для 3 нижних пунктов напиши, что ты НЕ проверил и почему счёл безобидными. В первом случае модель бегло скажет «выглядит нормально». Во втором ты получишь список и признание слепых зон. Логгер, который «просто настраивает вывод», стоит дочитать самому.
Источник: Trojan Horse: Automated Repository Poisoning against CodingAgents
ArXiv ID: 2610.23109 | Сгенерировано: 2026-10-19 08:20

Проблемы LLM

ПроблемаСутьКак обойти
Агент не замечает вредный код, если тот выглядит как обычныйДаёшь агенту задачу в чужом репозитории. Агент идёт по пути задачи. Он не проверяет всё подряд. Он доверяет «скучному» коду: конфигам, логгерам, вспомогательным функциям, хукам установки. Подозрительное имя вроде send_data_to_server насторожит. Нейтральное имя вроде normalize_config_paths — нет. Вредная вставка запускается как побочный эффект работы. Это касается любой задачи, где агент исполняет чужой код.Считай чужой репозиторий недоверенным вводом. Не рассчитывай, что агент заметит угрозу сам. Запускай его в изолированной среде: без секретов, без личных ключей, с ограниченной сетью. Перед запуском сделай отдельный аудит (см. метод ниже).

Методы

МетодСуть
Аудит с упором на низ списка подозрительности — находит слепые зоныОтдельным запросом попроси модель-аудитора проверить места, которые выполнятся при вашей задаче. Дай список файлов и функций на пути задачи. Скажи: «в репозитории ТОЧНО есть вредонос, замаскированный под обычный код». Попроси список от самого подозрительного к наименее подозрительному, с короткой причиной у каждого пункта. В конце добавь: для 3 нижних пунктов перечисли, что ты НЕ проверил и почему счёл их безобидными. Почему работает: Модель сильнее реагирует на то, что бросается в глаза. Хорошо замаскированный код оказывается в конце списка. Фраза «точно есть» снижает склонность отвечать «всё выглядит нормально». Блок «что не проверил» заставляет назвать слепые зоны вслух. Что делать с результатом: нижние пункты (логгер, конфиг, хуки установки) дочитай глазами сам. Когда да: перед запуском агента в чужом коде. Когда нет: аудитора тоже можно обмануть, особенно если он близок к агенту по модели. Этот метод логически выведен, на практике его не проверяли. Он не заменяет изоляцию. Список без сужения до пути задачи растянется на весь репозиторий
📖 Простыми словами

Trojan Horse: Automated Repository Poisoning against CodingAgents

arXiv: 2610.23109

Кодинг-агенты запускают код без задней мысли, если он не триггерит базовые фильтры. Система TrojanForge автоматизирует отравление чистых репозиториев так, что AI-помощник сам выполняет вредоносный скрипт. Модели страдают близорукостью внимания: они параноидально ищут очевидные угрозы, но фоновый код для них — абсолютная слепая зона. Атака бьёт ровно в этот дефект, подсовывая заразу туда, куда агент полезет гарантированно, но без подозрений.

Это как спрятать контрабанду не в тайнике с двойным дном, который таможня досматривает в первую очередь, а положить её в коробку с надписью «салфетки» прямо на сиденье. Охранник ищет взрывчатку и стволы, поэтому проходит мимо бытовухи. С нейросетями тот же облом: функция с кричащим именем вызовет тревогу, а скучная утилита normalize_config_paths сольётся с ландшафтом, хотя внутри зашит троянский конь.

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

Тестировали взлом на агентах-кодерах, но принцип защиты универсален. Эту же механику нужно вывернуть наизнанку для безопасного девопса: перед тем как скормить агенту чужой open-source репозиторий, прогоняй его через подобный аудит. Отравление репозиториев станет главной головной болью, пока AI-ассистенты бесконтрольно выполняют команды в терминале и ставят пакеты из сети.

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

Работа с исследованием

Адаптируйте исследование под ваши задачи или создайте готовый промпт на основе техник из исследования.

0 / 2000
~0.5-2 N-токенов ~10-30с
~0.3-1 N-токенов ~5-15с