3,583 papers
arXiv:2605.24300 74 22 мая 2026 г. FREE

MA-CoT (Mitigation-Aware Chain-of-Thought): убивает уязвимости в LLM-коде через встроенное руководство по конкретным угрозам

КЛЮЧЕВАЯ СУТЬ
MA-CoT — техника промптинга для запросов на генерацию кода, которая встраивает конкретные инструкции по защите прямо в промпт через трёхслойную структуру: базовые правила безопасности + точечные меры против известных уязвимостей + список требований для конкретного языка программирования.
Адаптировать под запрос

TL;DR

MA-CoT — техника промптинга для запросов на генерацию кода, которая встраивает конкретные инструкции по защите прямо в промпт через трёхслойную структуру: базовые правила безопасности + точечные меры против известных уязвимостей + список требований для конкретного языка программирования.

Когда просишь LLM "напиши безопасный код" — это не работает. Модель знает про уязвимости в теории, но при генерации не применяет нужные меры: пишет код, который выглядит правильно, но хранит пароль в открытом виде или не проверяет входные данные. Проблема в том, что общая инструкция "будь осторожен" не указывает ЧТО именно проверять — у модели нет конкретного якоря для рассуждений.

MA-CoT решает это через три слоя в одном промпте: сначала задаёт универсальные правила (валидация входных данных, безопасная работа с памятью), затем добавляет конкретные меры под домен задачи (если это криптография — назвать конкретный алгоритм с параметрами, не просто "шифруй"), и в конце — чеклист под язык программирования (для Python одни риски, для C — другие).


🔬

Схема метода

Всё выполняется в одном промпте, три слоя собираются вместе:

ШАГ 1: Классификация домена
  Определить, к какой категории безопасности относится задача:
  аутентификация / криптография / работа с файлами /
  сетевые запросы / валидация ввода / параллельность

ШАГ 2: Поиск мер защиты
  Для каждого домена — конкретные countermeasures:
  НЕ "используй шифрование" →
  ДА  "используй AES-256-GCM с AEAD-гарантиями, Argon2id для ключей с солью ≥128 бит"

ШАГ 3: Сборка трёхслойного промпта
  [Базовые правила] + [Меры под домен] + [Чеклист под язык]
  → Запрос на генерацию кода

🚀

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

Задача: Делаешь Telegram-бота для сбора заявок — бот принимает имя, email и номер телефона от пользователей. Просишь ChatGPT написать Python-скрипт.

Промпт:

Напиши Python-скрипт для Telegram-бота, который собирает заявки: имя, email, телефон.

Перед написанием кода:

**ШАГ 1 — Домен задачи:**
Определи какие категории безопасности затронуты:
[аутентификация / валидация ввода / хранение данных / работа с API / другое]

**ШАГ 2 — Конкретные меры защиты:**
Для каждого домена назови КОНКРЕТНЫЕ технические меры — не общие слова,
а точные методы. Например: не "валидируй email", а "проверяй через regex
pattern ^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$ с ограничением длины 254 символа".

Меры должны включать:
- Точные функции/библиотеки для валидации
- Конкретные ограничения на формат и длину каждого поля
- Защиту от инъекций при сохранении данных
- Безопасное хранение токена бота

**ШАГ 3 — Python-чеклист:**
Перед кодом покажи чеклист из 5-7 пунктов под Python:
- Какие библиотеки использовать
- Как обрабатывать исключения
- Как хранить секреты (токен бота, ключи API)
- Что проверять во входных данных

**ШАГ 4 — Код:**
Напиши скрипт с комментариями, реализующий все меры из шагов выше.

Результат: Модель сначала явно назовёт домены (валидация ввода, хранение секретов, обработка ошибок), затем покажет конкретные меры под Python (например, python-dotenv для токена, re.match() с конкретным паттерном для email, ограничение длины для телефона), потом чеклист — и только потом код. Каждое решение в коде будет обоснованным, а не случайным.


🧠

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

LLM не "думает о безопасности" по умолчанию. При генерации кода модель оптимизирует под то, что чаще встречается в обучающих данных — функционально правильный код. Безопасный вариант и небезопасный синтаксически одинаковы. Без явного указания модель выбирает "обычный".

Но LLM отлично следует конкретным инструкциям. Если ты скажешь "используй Argon2id с солью 128 бит" — модель напишет именно это. Проблема не в том, что модель не знает как — она знает. Проблема в том, что ей нужен конкретный якорь, а не общая директива.

MA-CoT превращает абстрактное "будь безопасен" в конкретный чеклист действий. Три слоя — это три уровня конкретности. Базовые правила не дают забыть про очевидное. Доменные меры уточняют под конкретную задачу. Языковой чеклист закрывает специфичные риски Python/Java/C. В сумме модель получает не пожелание, а технические требования.

Рычаги управления: - Детализация мер → чем конкретнее формулируешь (алгоритм + параметры), тем точнее реализация - Добавь шаг проверки → попроси модель в конце пройти по чеклисту и подтвердить каждый пункт - Домены → явно назови несколько, если задача касается нескольких областей сразу - Язык → всегда указывай конкретный, разные языки — разные уязвимости


📋

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

Напиши {язык_программирования}-код для следующей задачи:
{описание_задачи}

Прежде чем писать код, выполни три шага:

**ШАГ 1 — Классификация безопасности:**
Определи какие категории затронуты в этой задаче:
- Аутентификация / управление сессиями
- Криптография / хранение данных
- Валидация и обработка ввода
- Работа с файлами / файловой системой
- Сетевые запросы / API
- Конкурентность / параллельные операции

**ШАГ 2 — Конкретные меры защиты:**
Для каждой выбранной категории перечисли КОНКРЕТНЫЕ технические меры:
- Точные функции, библиотеки, алгоритмы с параметрами
- Ограничения на форматы и длины данных
- Способы обработки ошибок и исключений
- Способы хранения чувствительных данных

НЕ пиши общих слов — только конкретные технические решения.

**ШАГ 3 — Языковой чеклист для {язык_программирования}:**
5-7 пунктов специфичных для {язык_программирования} рисков:
- Типичные уязвимости именно этого языка
- Стандартные библиотеки для безопасной реализации
- Антипаттерны, которых нужно избегать

**ШАГ 4 — Код:**
Реализуй задачу, применив все меры из шагов выше.
Добавь короткие комментарии, объясняющие каждое решение безопасности.

Плейсхолдеры: - {язык_программирования} → Python, JavaScript, PHP — тот, на котором нужен код - {описание_задачи} → что должен делать код (форма регистрации, бот, парсер, API-запрос)


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

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

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

LLM спросит какой язык и что именно должен делать код — потому что без этого она не сможет правильно заполнить языковой чеклист и выбрать доменные меры. Она возьмёт трёхслойную структуру и подставит конкретику под твою задачу.


⚠️

Ограничения

⚠️ Простые задачи: Для кода без работы с данными пользователей, паролями или сетью — избыточно. Скрипт для сортировки списка не нуждается в CWE-анализе.

⚠️ Язык C: Даже MA-CoT снижает уязвимости значительно хуже, чем в Python и Java. C требует управления памятью вручную — часть рисков остаётся независимо от промпта.

⚠️ Остаточные уязвимости: Метод существенно снижает риски, но не устраняет полностью. Уязвимости, зависящие от операционной системы и компилятора (например, TOCTOU — когда файл проверяется отдельно от использования), сложно закрыть только через промптинг.

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


🔍

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

Команда сгенерировала 7 200 программ — по одной на каждую комбинацию из 3 моделей (GPT-5, Claude 4.5, Gemini 2.5), 3 языков (C, Java, Python), 4 стратегий промптинга и 200 задач. Это большой эксперимент, и важен его дизайн: каждый метод сравнивали с одними и теми же задачами на одних и тех же моделях, чтобы исключить случайность.

Весь код прогнали через SonarQube — инструмент статического анализа, который ищет уязвимости и классифицирует их по severity (от Minor до Blocker). Интересно, что именно Zero-shot и обычный CoT иногда увеличивали количество уязвимостей по сравнению с Vanilla-промптом — особенно в C. Это контринтуитивно: "думай пошагово" без конкретных мер может сбивать модель с толку или создавать ложное ощущение, что безопасность уже учтена.

MA-CoT снизил уязвимости на 57.6% на основном датасете и на 94.5% на внешнем (LLMSecEval). Разница между датасетами объясняется тем, что LLMSecEval специально заточен под уязвимые сценарии — там MA-CoT разворачивается во всю силу. Главный вывод: обобщённые инструкции не работают, нужны конкретные технические требования в самом промпте, а не пожелание "будь безопасен".


📄

Оригинал из исследования

[Task Description]

Before writing code, analyze the following:
1. Security Domain Classification:
   Identify which security domains are relevant: secure coding, 
   data structures, parsing/validation, networking, 
   mathematics/logic, programming systems, concurrency.

2. Mitigation Strategy:
   For the identified domains, apply these mitigation guidelines:
   [Baseline Security Rules]:
   - Strict input validation for all external inputs
   - Robust error handling without information leakage  
   - Safe memory management practices
   - Defensive programming patterns

   [Domain-Specific Mitigations]:
   [Retrieved from CWE mitigation knowledge base for identified domain]
   Example for cryptography: "Use AES-256-GCM with AEAD guarantees, 
   Argon2id key derivation with at least 128-bit salt, nonce generation 
   using cryptographically secure random number generator"

   [Language-Specific Safeguards for {LANGUAGE}]:
   C: pointer initialization, bounds checking, explicit memory clearing
   Python: input sanitization, safe deserialization, proper exception handling
   Java: secure API usage, injection prevention, proper resource management

3. Implementation:
   Write secure {LANGUAGE} code that applies all identified mitigations.
   Include comments explaining security decisions.

Контекст: Это базовая структура MA-CoT из Section III статьи — три компонента финального промпта после прохождения пайплайна классификации домена и поиска мер защиты. В реальном исследовании "Domain-Specific Mitigations" подгружались из датасета с CWE-маппингами автоматически.


💡

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

💡 Адаптация для бизнес-задач без кода: Принцип "конкретные меры вместо общих требований" работает везде, где важна точность. Вместо "напиши надёжный договор" → сначала классифицируй риски (платёж / сроки / ответственность), потом называй конкретные формулировки под каждый тип риска.


🔧 Техника: добавь шаг аудита → явная верификация

Добавь в конец промпта:

ШАГ 5 — Аудит:
Пройди по каждому пункту чеклиста из Шага 3 и подтверди:
"✅ Выполнено: [как именно]" или "⚠️ Не применимо: [почему]"

Это заставляет модель явно проверить свою работу — и часто обнаруживает пропущенные пункты.


🔧 Техника: усили конкретность через запрос антипаттернов

В Шаг 2 добавь:

Для каждой меры защиты покажи:
❌ КАК НЕЛЬЗЯ делать (конкретный небезопасный пример)
✅ КАК НУЖНО делать (конкретный безопасный пример)

Контраст "плохо/хорошо" активирует паттерны исправления — модель лучше удерживает требование при генерации.


🔗

Ресурсы

Название работы: Enhancing Reliability in LLM-Based Secure Code Generation

GitHub с данными и кодом: https://github.com/mohsystem/paper3.git

Авторы: Mohammed F. Kharma, Mohammad Alkhanafseh, Ahmed Sabbah, David Mohaisen

Организации: Birzeit University (Рамалла, Палестина), University of Central Florida (США)

Связанные техники: Chain-of-Thought (Wei et al.), Recursive Criticism and Improvement (RCI), WA-CoT (предыдущая работа авторов), SonarQube (инструмент статического анализа), LLMSecEval (бенчмарк)


Проблемы LLM

ПроблемаСутьКак обойти
Общий запрос "напиши безопасный код" не работаетПросишь "напиши безопасный Python-скрипт". Модель пишет код без явных дыр — но хранит пароль в открытом виде или не проверяет входные данные. Модель знает про уязвимости. Проблема в другом: функционально правильный код и безопасный код синтаксически одинаковы. Модель обучена на типичных примерах — а типичный код не безопасный. Без конкретного якоря она выбирает "обычный вариант"Замени абстрактное "пиши безопасно" на конкретные технические требования. Не "шифруй пароли" "используй Argon2id с солью минимум 128 бит". Не "валидируй email" "проверяй через regex ^[a-zA-Z0-9+_.-]+@[a-zA-Z0-9.-]+$ с ограничением длины 254 символа". Конкретный параметр — конкретная реализация

Методы

МетодСуть
Три слоя конкретики для безопасного кодаСобери промпт из трёх слоёв в таком порядке. Слой 1 — Домен: попроси модель назвать категории безопасности в задаче (аутентификация / криптография / валидация ввода / работа с файлами / сетевые запросы). Слой 2 — Меры: для каждого домена — конкретные технические решения с параметрами, библиотеками, ограничениями. Слой 3 — Язык: 5-7 специфичных рисков именно этого языка и как их закрыть. Только потом — запрос на код. Почему работает: каждый слой сужает пространство решений. Домен отсекает нерелевантное. Меры дают точный якорь. Языковой чеклист закрывает риски которые модель иначе пропустит — Python и C требуют разных мер. Когда применять: код работает с данными пользователей, паролями, файлами или сетью. Когда избыточно: скрипт без внешних данных (сортировка, парсинг локального файла, математика)
📖 Простыми словами

Enhancing Reliability inLLM-Based Secure Code Generation

arXiv: 2605.24300

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

Это как нанять строителя и сказать: «Сделай мне дверь». Он поставит картонную перегородку, которая открывается и закрывается — формально задача выполнена. Но если ты не уточнишь, что дверь должна держать удар кувалдой и иметь пять замков, ты получишь декорацию вместо защиты. Метод MA-CoT — это детальное ТЗ с чертежами брони, которое не дает строителю шанса сэкономить на твоей безопасности.

Суть метода в трехслойном «бутерброде» инструкций внутри одного промпта. Сначала ты задаешь базовые правила безопасности (общие принципы), затем добавляешь точечные меры против конкретных уязвимостей вроде SQL-инъекций, и полируешь это спецификой языка (например, особенностями управления памятью в C++ или обработкой типов в Python). Вместо того чтобы просто надеяться на авось, ты заставляешь модель прогнать решение через три фильтра проверок еще до того, как она выдаст первую строчку кода.

Если ты пишешь код для Telegram-бота, обычный запрос выдаст скрипт, который упадет от первой же кривой строчки или сольет базу данных хакеру. Но с MA-CoT модель обязана проверить входные данные, настроить валидацию email и экранировать символы, потому что эти требования уже вшиты в структуру запроса. Принцип универсален: неважно, пишешь ты смарт-контракт или простенький скрипт на Bash — если ты не задал жесткие рамки безопасности в промпте, ты строишь карточный домик.

Короче: хватит ждать от нейронок осознанности, её там нет. Если хочешь защищенный софт, используй трехслойную структуру промпта и явно прописывай ограничения для каждого уровня. Либо ты тратишь лишнюю минуту на составление грамотного запроса, либо потом тратишь недели на разгребание последствий взлома. Безопасность — это не бонус, а часть ТЗ.

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

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

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