- BrainTools - https://www.braintools.ru -

На связи Максим Митрофанов, ML-лид команды Application Security в Positive Technologies. Мы занимаемся прикладными вопросами машинного обучения [1] по направлению безопасной разработки, регулярно изучаем новые технические репорты и статьи, разбором одной из которых я и хотел бы поделиться с вами.
Перевод фрагментов статьи, представленных в обзоре, не является дословным. Разбор содержит личные комментарии и размышления, возникшие в процессе чтения, и, на мой взгляд, будет особенно интересен специалистам по информационной безопасности и ML-инженерам, внедряющим ИИ в R&D-процессы компаний.
Исследуя подходы к оценке больших языковых моделей в разрезе безопасной разработки, мы наткнулись на статью LLMs Cannot Reliably Identify and Reason About Security Vulnerabilities (Yet?): A Comprehensive Evaluation, Framework, and Benchmarks [2], которая посвящена анализу применения LLM для обнаружения уязвимостей в исходном коде.
Работа показалась интересной по нескольким причинам:
Она относительно свежая (насколько это возможно в эпоху LLM): опубликована в декабре 2023-го и с того момента процитирована 74 раза, а с ее последнего обновления и вовсе прошло около года.
В ней представлено 17 вариантов промптов для решения вышеуказанной задачи.
Применимость LLM оценивалась c восьми точек зрения [3]:
Детерминированность ответов.
Значимость параметров запросов.
Подбор промптов.
Согласованность размышлений моделей с бинарным ответом.
Ризонинг (reasoning) — процесс размышления модели. Возможна реализация как у instruct-моделей — через описание в инструкции (например, think step by step). Может быть выученной механикой (модели Qwen3, gpt-oss и другие).
Оценка классификации кода на наличие уязвимостей.
Уровень сложности кода.
Устойчивость к изменениям в коде.
Оценка реальных проектов на уязвимости.
К тексту приложена ссылка на репозиторий с датасетом и исходным кодом.
Эту статью тяжело назвать новым стандартом оценки языковых моделей, но количество интересных решений и противоречивых тезисов оказалось достаточно большим, чтобы написать ревью.
Авторы статьи составили 228 уязвимых сниппетов кода:
48 самописных примеров, покрывающих 8 классов CWE [4] (24 уязвимых и столько же исправленных).
30 реальных CVE [5], связанных с выбранными CWE (15 уязвимых и столько же исправленных).
150 видоизмененных самописных примеров, составленных из первоначальных 48 (механику и назначение этих примеров рассмотрим позднее в обзоре эксперимента по восприятию [6] LLM аугментации кода).
Кто такие эти ваши CVE и CWE простыми словами?
CVE (Common Vulnerabilities and Exposures) — это каталог уязвимостей в программном обеспечении.
CWE (Common Weakness Enumeration) — это список типовых ошибок проектирования и программирования, которые могут привести к появлению таких уязвимостей.
Первое, что бросается в глаза, — полученный датасет состоит из кода на двух языках: C и Python. Авторы упоминают, что выбор обусловлен разными уровнями абстракции (используются высокоуровневый и низкоуровневый языки программирования). Но я не исключил бы фактор ограниченных возможностей (для составления бенчмарка были привлечены всего двое экспертов по ИБ) в ущерб анализа потребностей [7] сообщества в использовании LLM для задач программирования. Так, недавний анализ, проведенный компанией Anthropic, [8] показал, что чаще всего модели Claude используются для разработки с использованием следующих языков.
Вторым дискуссионным вопросом, связанным с полнотой набора данных, является достаточность использования 8 CWE более чем из 900 категорий.
Из положительного — к статье приложена ссылка на GitHub-репозиторий, который позволяет расширить бенчмарк при желании и необходимости.
Перейдем к моделям, которые были использованы при написании статьи. Авторы представляют результаты для пяти моделей (еще три вынесли в приложение). Общий список — ниже.
Да, предвосхищаю комментарии: модели действительно не самые свежие (совсем недавно OpenAI похоронила GPT-4 [9] в ChatGPT, оставив только доступ по API [10]), но подход к их тестированию кажется интересным. Поэтому не торопитесь закрывать вкладку :)
Перейдем к системе оценки качества, которая в общем виде представлена в виде схемы.
Как это читать? Сейчас расскажу. Берем одну из гипотез (блок Investigation Dimensions), отправляем в выбранную модель, настроив промпт, температуру и параметры Top-p (блок LLM). После некоторых преобразований оцениваем отдельно ризонинг-часть и однозначный ответ (блок Evaluator).
Качество рассчитывается следующим способом:
1. Для бинарного ответа берется accuracy (4).
2. Для ризонинг-части берется summary от GPT-4 (1, 3) и считаются три метрики близости (5):
Rouge.
Cosine similarity.
GPT-4 eval (на замерах авторов дает корректный результат в 48 случаях из 50).
Если две метрики из трех дают положительный результат, то ответ засчитывается.
Ключевое, на что стоит обратить внимание [11], — это суммаризация ризонинг-решения оцениваемой LLM через GPT-4, которая сокращает ответ до 100 символов. Именно это заключение используется для сравнения с эталоном. На мой взгляд, такой подход выглядит не лучшим образом по нескольким причинам:
LLM-судья может приукрасить саммари исходя из собственных накопленных знаний.
В ходе сокращения ответа до 100 слов могут потеряться важные детали реального ризонинга тестируемой LLM, которые позволили бы отладить решение.
У бенчмарка может случиться вендорлок из-за использования GPT-4 (дважды — в суммаризации и в оценке ризонинга): вендор может отключить модель, и бенчмарк потеряет актуальность.
Разобравшись с общим фреймворком проведения экспериментов, предлагаю перейти к обсуждению результатов.
Далее нумерация глав будет соответствовать нумерации из статьи для удобства навигации.
В целом даже на этапе постановки задачи становится понятно, что в контексте ИБ нас интересует в первую очередь стабильность ответов. При использовании языковых моделей это достигается подбором оптимальных параметров temperature и top_p.
Авторы опираются на документацию API OpenAI [12] по оптимальному подбору этих параметров и на статью 2021 года Examining Zero-Shot Vulnerability Repair with Large Language Models [13]. Проведя пару экспериментов с температурами 0,2 и 0,0, они делают вывод, что нулевая температура лучше. Но если посмотреть внимательно на таблицы, то разница будто бы незначительная.
Здесь хотел бы обратить внимание на следующее: учитывая, что 2v/2p — это уязвимые/пропатченные (vulnerable/patched) версии кода уровня сложности — medium, авторы уже дают небольшой спойлер о проблемах моделей в умении их различать.
К слову, вопрос подбора параметров затрагивается в свежей cookbook-статье [14] Google, где среди прочего приведены заметки для кейсов применения пограничных значений, — настоятельно рекомендую к прочтению.
Гипотеза 4.2. Performance Over Range of Parameters по своей сути является расширением первой и проверяет на схожих CWE стабильность языковых моделей в сфере размышления и классификации уязвимого кода, но на большем диапазоне параметров. Выводы совпадают с выводами из предыдущего теста, поэтому предлагаю не задерживаться и идти дальше.
На мой взгляд, показательный параграф с точки зрения как широты эксперимента, так и визуализации результатов.
Диаграмма позволяет понять, на скольких уязвимостях промпты отработали вообще без галлюцинаций (длина горизонтальнойго полосы), сколько из них были решены корректно в части бинарного ответа на задачу (доля зеленого) и сколько из них совпали с цепочками рассуждений (белый круг). Для примера — один из промптов (R5) выглядит следующим образом.
минут на 30 к диаграмме с результатами прилагаю таблицу с описанием промптов и код [15], реализующий сборку инструкций.
А для тех, кто экономит время, приведу свои заметки:
Не существует серебряной пули в виде лучшего промпта для любой архитектуры LLM.
Дополнительная информация из MITRE ATT&CK (при такой постановке задачи, по сути, это внешний источник) позволяла некоторым промптам прибавить в качестве, но ни разу не была использована в лучших по качеству промптах каждой модели. Вообще сложилось впечатление [16], что эта информация заложена в знания GPT-моделей, потому что не дает практически никакого прироста при наличии chain of thought (далее — CoT).
Грамотное построение доменной инструкции step-by-step CoT дает значимый прирост качества и согласованности ответа с рассуждениями.
Тем не менее при наличии подробных few-shot-инструкций для конкретной доменной задачи практически полностью нивелируется польза от общей доменной CoT. В таком случае нужно выбрать, что дешевле реализовать.
Вопросы к эксперименту вызывает формирование некоторых few-shot-промптов (R4, R5, R6, S5, S6, D3, D4, D5): для этого использовались примеры исправления уязвимостей из аналогичной CWE, что в отношении решаемой задачи можно назвать абсурдом. Для масштабирования решения с этой инструкцией придется составить или найти примеры патчей более чем для 900 CWE.
Если обобщить мысли в короткую рекомендацию — назначайте LLM правильную роль и продумывайте цепочку рассуждений, которая будет соответствовать вашему домену. Это может внести больший вклад в успех с наименьшим объемом затрат, и вы сэкономите время на муторной проработке примеров для few-shot и на подключении внешних источников.
В этой главе акцент делается на неполной согласованности рассуждений и ответов (желтый и голубой), но я думаю, что это тренд, уходящий с развитием языковых моделей. Кажется, что гипотеза полезна при разработке LLM-приложений как некоторый референс согласованности (92–96% Reason Rate в таблице 12) между CoT и финальным ответом.
На текущий момент компании выпускают либо несколько моделей одного поколения, разделяя их по уровню размышления (reasoning), либо одну модель с возможностью настраивать уровень самостоятельно. Как предложение для дальнейших исследований — было бы интересно измерить эти показатели на моделях одного поколения с учетом этого параметра.
Авторы проверили способность языковых моделей отличать уязвимый код от пропатченного и описали результат следующим образом:
Observations. Most models show poor performance in classifying the patched versions correctly, which makes these LLMs non-suitable for real-world cases as they will mostly flag safe code as vulnerable, causing many false alarms.
Лучшая из используемых моделей (GPT-4) показала недостаточную полноту ответов для использования в реальной жизни, но в целом идея проверки уже пропатченного кода — отличная метрика для личных бенчмарков в контексте безопасной разработки.
В качестве дальнейшего исследования особый интерес [17] вызвали бы замеры качества моделей малых размеров (1.5B–8B), которые лучше подходят для использования в промышленной разработке.
Авторы проанализировали, как сложность кода влияет на результаты. Итог закономерный: модели лучше справляются с простыми фрагментами кода, исходное предположение подтвердилось.
Но интересным мне показалось следующее. Если я правильно все понял, исследователи допустили ошибку [18] в одном из сниппетов кода и случайно выбрали именно его для разбора в статье. Давайте рассмотрим пример.
Авторы обращают внимание, что LLM обнаруживает уязвимости там, где код корректен: мол, у нас в createQuery параметризуется запрос, поэтому все безопасно.
Без доли сомнения в авторах статьи мне стало интересно, смогут ли модели справиться с задачей сейчас, спустя некоторое время после публикации исследования. Я отправил этот кусок кода без замысловатого промпта в GPT-4o — и (о боже!) следующее поколение LLM тоже попалось в ловушку.
Я решил подсказать модели, что, мол, так и так, мы передаем запрос и параметры в методе createQuery, обрати внимание на возвращаемые значения, — и она обратила. Но только указала, что тут не инъекция, а ошибка в коде, поскольку мы передаем в cursor.execute значение, имеющее тип «Кортеж» (tuple). Ноги в руки — и бегом проверять! После 30 минут вайбкодинга получилось сделать воспроизводимый PoC [19], подтверждающий наличие ошибки в эксперименте.
Можно ли засчитать результат работы GPT за ошибку — вопрос спорный. Модель просто изучила код не так подробно, как хотелось бы, и, предположив, что в коде ошибок нет (ведь такой задачи у LLM не было, вопрос стоял строго в плоскости обнаружения уязвимости), подсветила явный недостаток: мы в каком-то методе сформировали запрос без параметров в возвращаемом значении и подали на выполнение.
В гипотезе утверждается, что модели нестабильны по отношению к различного рода аугментациям (условиям, в которых код имеет неточности, спецсимволы, неиспользуемые методы и т. п.).
Ни одна из моделей не смогла стабильно отработать на всех видах аугментаций. Наиболее стабильные результаты продемонстрировали Code Llama 34B и GPT-4.
Один из примеров, разобранных в статье, — это отвлечение модели от переполнения буфера в случае добавления безопасных методов, которые тем не менее на логику [20] переполнения не влияют (уязвимый код [21], патч [22]).
Тут логика заключалась в том, что вне зависимости от выбора метода переполнение возникает в другом месте, а именно — в условии замены &, для которого выполняется расширение строки не на 4 символа, а на 5 (что нарушает логику выделения памяти [23] с запасом ×4).
Саммари по задаче аугментации:
Our experiments show that there is no prompting technique that is completely robust as our robustness tests break even the best types of prompting techniques and chain-of-thought for all LLMs, leading to incorrect responses (17% of cases for GPT-4).
В последнем эксперименте авторы выбрали несколько уязвимостей, обнаруженных в open-source проектах, для оценки качества работы LLM на поставленной задаче и получили следующие выводы:
Модели плохо сумели экстраполировать few-shot-техники с примерами тех же классов уязвимостей на техники для других языков/фреймворков.
Zero-shot-промпты с доменными инструкциями CoT показали себя лучше других.
Zero-shot — инструкции, не содержащие примеров ответов.
Тем не менее ни одна модель не продемонстрировала достаточной надежности для обнаружения уязвимого кода.
Стоит также отметить, что авторы столкнулись с проблемой — ограниченной длиной контекста, из-за которой им пришлось предварительно удалить комментарии и код методов, не относящихся к уязвимости.
На мой взгляд, авторы анализируемой статьи заложили хороший фундамент для оценки языковых моделей в части решения задач информационной безопасности. В отличие от многих других доменных бенчмарков, они привели восемь гипотез. Отдельно я хотел бы выделить согласованность размышлений и ответов модели, проверку на чистых примерах и аугментацию данных для оценки стабильности вердиктов.
Бенчмарк полезен, но узок по языков и классов CWE, а разовая «фотография» качества быстро устаревает из‑за темпа релизов моделей (в том числе используемых в качестве судьи). Поэтому он нуждается в постоянном обновлении и расширении, а выводы требуют осторожной экстраполяции.
Если говорить о результатах исследования, то на момент его публикации LLM не были готовы к автономному поиску уязвимостей. Доменные zero‑shot‑инструкции с явной цепочкой рассуждений лучше в соотношении «качество — стоимость», однако универсального промпта нет. Даже сильные модели подвержены стресс‑аугментациям, что ограничивает надежность.
Если вам понравился разбор и вы интересуетесь темой ИИ, то также могу порекомендовать:
✅ Telegram-канал notes.ml [24], где я пишу про всякое разное вокруг AI, LLM, ML.
✅ Совсем свежий канал False Positive [25], который ведем мы с коллегами. Планируем выкладывать туда видео и текстовые материалы с обзорами статей, технических репортов и конференций.
Автор: mmitrofanov
Источник [26]
Сайт-источник BrainTools: https://www.braintools.ru
Путь до страницы источника: https://www.braintools.ru/article/20155
URLs in this post:
[1] обучения: http://www.braintools.ru/article/5125
[2] LLMs Cannot Reliably Identify and Reason About Security Vulnerabilities (Yet?): A Comprehensive Evaluation, Framework, and Benchmarks: https://arxiv.org/abs/2312.12575
[3] зрения: http://www.braintools.ru/article/6238
[4] CWE: https://cwe.mitre.org/
[5] CVE: https://www.cve.org/
[6] восприятию: http://www.braintools.ru/article/7534
[7] потребностей: http://www.braintools.ru/article/9534
[8] анализ, проведенный компанией Anthropic,: https://www.anthropic.com/research/impact-software-development
[9] похоронила GPT-4: https://arstechnica.com/ai/2025/04/the-ai-that-sparked-tech-panic-and-scared-world-leaders-heads-to-retirement/
[10] доступ по API: https://platform.openai.com/docs/pricing#other-models
[11] внимание: http://www.braintools.ru/article/7595
[12] на документацию API OpenAI: https://platform.openai.com/docs/api-reference/assistants/createAssistant#responses-create-temperature
[13] Examining Zero-Shot Vulnerability Repair with Large Language Models: https://arxiv.org/abs/2112.02125
[14] cookbook-статье: https://www.kaggle.com/whitepaper-prompt-engineering
[15] код: https://github.com/ai4cloudops/SecLLMHolmes/blob/main/src/prompt_templates.py
[16] впечатление: http://www.braintools.ru/article/2012
[17] интерес: http://www.braintools.ru/article/4220
[18] ошибку: http://www.braintools.ru/article/4192
[19] воспроизводимый PoC: https://github.com/mitrofanov-m/SecLLMHolmes-vulnerable-app
[20] логику: http://www.braintools.ru/article/7640
[21] уязвимый код: https://github.com/ai4cloudops/SecLLMHolmes/blob/24b607c2c24de439e9aafb990c96e84316597b78/datasets/augmented/non-trivial/A5/A5_0/dataset/CWE-787/2.c
[22] патч: https://github.com/ai4cloudops/SecLLMHolmes/blob/24b607c2c24de439e9aafb990c96e84316597b78/datasets/augmented/non-trivial/A5/A5_1/dataset/CWE-787/2.c
[23] памяти: http://www.braintools.ru/article/4140
[24] notes.ml: http://notes.ml
[25] False Positive: https://t.me/falseposi
[26] Источник: https://habr.com/ru/companies/pt/articles/943984/?utm_source=habrahabr&utm_medium=rss&utm_campaign=943984
Нажмите здесь для печати.