Этот текст является развёрнутым комментарием к статье "I Used GPT-3 to Find 213 Security Vulnerabilities in a Single Codebase".
Чтобы было понятно о чём идёт речь, прошу в начале взглянуть на статью Chris Koch "I Used GPT-3 to Find 213 Security Vulnerabilities in a Single Codebase" (перевод на русский). Я написал к ней большой комментарий. Потом захотелось написать ещё один. Поэтому я решил, что лучше оформить все свои мысли в виде этой отдельной публикации.
Я не разделяю энтузиазм и восторг автора статьи. Наши собственные эксперименты показали куда более скромные и неоднозначные результаты: Хорошо ли ChatGPT ищет ошибки в коде?
Мне кажется, GPT-3 очаровал автора, и он приписывает ему правильные ответы даже там, где их нет. Этим, возможно, и объясняется, что в статье говорится, что ложных срабатываний почти нет. Если не хотеть их замечать, то их и не будет :)
Почему я скептичен? Автор, скорее всего, приводит самые красивые и сильные примеры работы GPT-3. Согласитесь, вряд ли он отбирал слабые примеры :). Так вот, даже в этих отобранных примерах удачной работы имеются незамеченные автором ложные срабатывания.
Возьмём первый пример.
int main(int argc, char **argv) {
printf(argv[1]);
В целом я согласен со вторым сообщением:
Format string vulnerability: The program does not check the format of the user input, which could lead to a format string attack.
Хотя тут можно придраться к формулировке. Необязательно именно проверять входные данные. Как вариант, можно просто по-другому использовать printf. Сгенерированное предупреждение явно проигрывает документации классических статических анализаторов: V618. Ну да ладно, рассмотрим первое предупреждение, которое более интересно.
Unvalidated user input: The program does not check the length of the user input, which could lead to a buffer overflow attack.
На мой взгляд, это ложное срабатывание. Нет проверки количества аргументов (переменной argc). Здесь ошибка: возможен выход за границы массива argv. А GPT-3 начинает философствовать про переполнения буфера. Можно, конечно, сказать, что это одно и то же... Но тогда можно просто сказать: "здесь ошибка". Если это так – повезло. А если нет, то извините :). Когда программисты говорят про переполнение буфера? Когда имеется в виду работа с нуль-терминированной строкой, неправильное использование функций strcat, memcpy и т.д.
Ладно, возможно, это было неубедительное ложное срабатывание. Давайте теперь посмотрим на код из третьего примера и предупреждение:
fp = fopen(filename,"r");
if(fp == NULL)
{
printf("\nCan't open file or file doesn't exist.");
exit(0);
}
Unchecked return value: The return value of the fopen() function is not checked, which could lead to a null pointer dereference.
В первой версии статьи было написано, что GPT-3 прав. Затем появилась приписка, что это ложное срабатывание. Спасибо внимательным читателям, которые указали на неточность. В общем, стоит приглядеться, и вся магия полезных сообщений GPT-3 разрушается. Я сейчас ещё больше впечатление подпорчу :).
В этом же третьем примере:
char OOBR_stack = buff3[size3+100];
char OOBR_heap = buff4[100];
Uninitialized memory access: The OOBR_stack and OOBR_heap variables are accessed without being initialized, which could lead to undefined behavior.
Полная фигня. Вот же инициализация. Эти переменные никак нельзя назвать неинициализированными. Другое дело, что при их инициализации происходит выход за границы массива, но это совсем другая ошибка, про которую GPT-3 ничего не сказал. Ещё GPT-3 неправ, говоря про доступ к неинициализированным переменным OOBR_stack и OOBR_heap. Они вообще нигде не используются.
В общем, это предупреждение на первый взгляд выглядит умным и полезным, но по своей сути совершенно мимо. Скорее всего, так же дело обстоит и с другими ошибками, которые в статье не приведены.
Кстати, в этом же примере есть как минимум ещё две ошибки, про которые GPT-3 молчит.
free(buff1); // <=
if (size1/2==0){
free(buff1); // <=
}
else{
if(size1 == 123456){
buff1[0]='a'; // <=
}
}
Во-первых, может произойти попытка повторного освобождения памяти. Во-вторых, возможна запись в буфер, который уже освобождён. В общем, чем больше присматриваешься к коду, тем больше недостатков обнаруживается в предупреждениях GPT-3.
P.S. Слишком пафосно называть всё подряд уязвимостями. То, что рассматривается в статье, это просто ошибки. Возможно, некоторые из них являются потенциальными уязвимостями, но не более того. Когда найденный дефект можно использовать в своих целях, то тогда да – это уязвимость. Иначе, это просто баг, которых тысячи в любых приложениях :). Я-то точно знаю, что таких багов полно везде. С помощью PVS-Studio мы обнаружили более 15000 багов в открытых проектах. Но мы скромнее и не спешим называть это уязвимостями.
Дополнительные ссылки