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 (бенчмарк)
