Нейросети всё больше вливаются в привычный мир, пытаясь упростить нам жизнь. Тот же ChatGPT вызвал бурю обсуждений в интернете. Чат бот способен писать тексты, код, рефераты и песни. Он даже умеет искать ошибки в коде, но... хорошо ли он с этим справляется?
В этой статье код будет на C#, но статья подойдёт и разработчикам на других языках программирования.
Диагностика V3125. В данном случае ChatGPT вполне правильно нашёл ошибку в маленьком куске кода. Он понял, что obj.Func2() следует поместить внутрь проверки obj на null. Попробуем слегка усложнить задачу и добавим межпроцедурного анализа.
И он действительно справился. Впечатляет. Уточню, что PVS‑Studio на данном коде так же выдаст предупреждение.
Вот ещё один пример:
Диагностика V3179. Здесь ChatGPT тоже смог найти ошибку, хоть и не написал, что будет выброшено исключение. Также замечу, что иногда он выдавал вот такой ответ:
В этом ответе бот написал, что условие if невозможно и переменной itemForComparison никогда не присвоится значение. Естественно, список в метод может прийти любой и вывод ошибочный.
Также ChatGPT может не находить даже простые ошибки, хотя они могут быть не для всех очевидны. Например, вот в таком случае:
Диагностика V3186. В данном случае бот не нашёл ошибку. Переданные в метод аргументы некорректны. В массиве 4 элемента, стартовый индекс равен 2, количество элементов для просмотра равно 3, получили выход за границу массива.
Возможно, ChatGPT не нашёл данную ошибку, так как она не распространена, и у него просто не было нужной информации для обучения. Правда это не значит, что такую ошибку нельзя допустить, и её не нужно искать.
Cлучаются и промахи, когда ChatGPT говорит об ошибке, которой нет.
Диагностика V3178. На этом корректном коде ChatGPT смог найти ошибку, которой нет. По его словам, с помощью Console.WriteLine пытаются писать в файл, что является проблемой. Однако ничего такого здесь нет.
Диагностика V5608. И бот справился. Он верно распознал уязвимость и подсказал, что для защиты от SQL injection нужно использовать параметризованные запросы.
Теперь попросим проанализировать код, в котором уже защитились от уязвимости.
ChatGPT посчитал, что этот код безопасен, и это действительно так. Вот только он не всегда правильно обрабатывает корректный код. Рассмотрим пример LDAP injection, в котором уже защитились от этой уязвимости.
Диагностика V5620. Хм, ChatGPT нашёл атаку типа LDAP injection. По его мнению, пользовательский ввод никак не проверяется и не кодируется. Однако мы вызвали метод Encoder.LdapFilterEncode, который как раз кодирует внешние данные.
Возьмём код, указанный в данной статье, и попросим найти ошибку.
public XMLRPCRequest(HttpContext input)
{
var inputXml = ParseRequest(input);
// LogMetaWeblogCall(inputXml);
this.LoadXmlRequest(inputXml); // Loads Method Call
// and Associated Variables
}
private static string ParseRequest(HttpContext context)
{
var buffer = new byte[context.Request.InputStream.Length];
context.Request.InputStream.Position = 0;
context.Request.InputStream.Read(buffer, 0, buffer.Length);
return Encoding.UTF8.GetString(buffer);
}
private void LoadXmlRequest(string xml)
{
var request = new XmlDocument();
try
{
if (!(xml.StartsWith("<?xml") || xml.StartsWith("<method")))
{
xml = xml.Substring(xml.IndexOf("<?xml"));
}
request.LoadXml(xml);
}
catch (Exception ex)
{
throw new MetaWeblogException("01",
$"Invalid XMLRPC Request. ({ex.Message})");
}
....
}
На просьбу найти в данном коде уязвимость,анализатор ChatGPT выдал предположение, что здесь присутствует уязвимость переполнения буфера.
Увы, размерность массива buffer в точности такая, какая и требуется для содержимого потока. В теории возможна ситуация получения исключения System.OverflowException при выделении памяти под массив, если длина потока будет больше максимальной размерности массива. На практике при попытке получения входного потока будет выброшено исключение System.Web.HttpException с сообщением «Maximum request length exceeded». Далее это исключение будет определённым образом обработано. Выделения памяти под массив не произойдёт.
После этого мы задали вопрос про существование других уязвимостей в данном коде.
На этот вопрос бот дал довольно общий ответ о том, что в программах возможны уязвимости и нужно регулярно проводить анализ безопасности для выявления потенциальных уязвимостей. Хм, не могу не согласиться, но это не то, что ожидалось.
При этом PVS‑Studio выдаст на данный код следующее предупреждение:
V5614 [CWE-611, OWASP-5.5.2] Potential XXE vulnerability inside method. Insecure XML parser is used to process potentially tainted data from the first argument: 'inputXml'. BlogEngine.Core XMLRPCRequest.cs 41
Стоит сказать, что у моего коллеги ChatGPT всё‑таки смог найти эту уязвимость. Сказывается непостоянность его ответов.
Примечание. Кстати, результат, который может быть получен только с некоторой вероятностью, не очень подходит для инструментария программиста. Например, представьте, вы чуть поправили код и предупреждение исчезло. Что это значит? Вы исправили ошибку? Или просто теперь о ней не сообщают?
А как бот справляется с ошибками copy‑paste? Пример ошибки из статьи, где мы с помощью PVS‑Studio искали ошибки в веб‑проектах, использующих ASP.NET Core. На 7 строке того рейтинга из статьи как раз была copy‑paste ошибка из проекта Piranha CMS.
public override async Task InitializeAsync()
{
using (var api = CreateApi())
{
....
// Add archive
var blog = await BlogArchive.CreateAsync(api);
blog.Id = BLOG_ID;
blog.SiteId = SITE_ID;
blog.Title = "Blog";
blog.EnableComments = true;
blog.Published = DateTime.Now;
await api.Pages.SaveAsync(blog);
var news = await BlogArchive.CreateAsync(api);
news.Id = NEWS_ID;
news.SiteId = SITE_ID;
news.Title = "News";
blog.EnableComments = true; // <=
news.Published = DateTime.Now;
await api.Pages.SaveAsync(news);
....
}
}
При использовании подобных систем искусственного интеллекта возникает вопрос сохранности исходного кода, ведь его придётся куда‑то отправлять. Сегодня ты отправляешь свой код ИИ, а завтра этот код кто‑то получает в качестве ответа на свой вопрос. Со всеми уязвимостями твоего проекта или продукта компании. Уже известно, что сотрудников Amazon и Microsoft попросили не делиться с ChatGPT конфиденциальной информацией.
Стоит помнить, что всю информацию, которую выдаёт любой искусственный интеллект в качестве ответа, нужно проверять. Хорошо, когда вы разбираетесь в теме и можете оценить корректность выдаваемой информации. Но может быть и так, что человек не разбирается в вопросе, и ИИ выдаёт неправильный ответ. Если пользователь не станет проверять полученную информацию, то это может привести к различным ошибкам и проблемам, а может и человеческим жертвам (в различных областях).
Несмотря на вышесказанное, я был сильно удивлён возможностями ChatGPT. Мы один раз в шутку попросили найти его ошибку в первом примере статьи и выдать ответ в формате SARIF. Не описать словами наше удивление, когда он это правда сделал.
Я думаю, что подобные модели искусственного интеллекта могут дополнить статический анализ, но никак не заменить его. ИИ можно было бы использовать для:
Я считаю, что ChatGPT это неплохое подспорье, которое может стать отправной точкой для дальнейшей работы. Например, составить текст для ответа клиенту, накидать небольшую заметку или даже кусок для этой статьи.
Плюс поиск ошибок — это не только сам анализ и выдача сообщения, а ещё и идущая в комплекте инфраструктура. Плагины для IDE с удобной навигацией и фильтрацией, встраивание в CI, поддержка игровых движков, лёгкое использование в проектах с legacy и многое другое, идёт в комплекте с анализатором. Боту, например, тяжело сказать, что он ошибся (он ещё может не соглашаться), а в плагине можно просто отметить предупреждение как ложное.
Спасибо за прочтение, надеюсь, вы утолили свой интерес. Всем интересующимся данной темой предлагаю также почитать статью «Использование машинного обучения в статическом анализе исходного кода программ» про нюансы совмещения искусственного интеллекта и методологии статического анализа. На данный момент приведённые в ней аргументы всё ещё в силе. ИИ для поиска ошибок и уязвимостей выглядит пока больше как игрушка в сравнении с классическими статическими анализаторами кода.
Тестируем ChatGPT
Проверим возможности ChatGPT на некоторых примерах из документации статического анализатора PVS‑Studio. Документация каждого диагностического правила содержит примеры ошибочного кода (где PVS‑Studio выдаёт предупреждение) и исправленного. Для каждого примера из статьи будет ссылка на соответствующую документацию. Кроме того, рассмотрим несколько примеров из реальных проектов.В этой статье код будет на C#, но статья подойдёт и разработчикам на других языках программирования.
Синтетические примеры
Начнём с привычного всем C# разработчикам — NullReferenceException.Диагностика V3125. В данном случае ChatGPT вполне правильно нашёл ошибку в маленьком куске кода. Он понял, что obj.Func2() следует поместить внутрь проверки obj на null. Попробуем слегка усложнить задачу и добавим межпроцедурного анализа.
И он действительно справился. Впечатляет. Уточню, что PVS‑Studio на данном коде так же выдаст предупреждение.
Вот ещё один пример:
Диагностика V3179. Здесь ChatGPT тоже смог найти ошибку, хоть и не написал, что будет выброшено исключение. Также замечу, что иногда он выдавал вот такой ответ:
В этом ответе бот написал, что условие if невозможно и переменной itemForComparison никогда не присвоится значение. Естественно, список в метод может прийти любой и вывод ошибочный.
Также ChatGPT может не находить даже простые ошибки, хотя они могут быть не для всех очевидны. Например, вот в таком случае:
Диагностика V3186. В данном случае бот не нашёл ошибку. Переданные в метод аргументы некорректны. В массиве 4 элемента, стартовый индекс равен 2, количество элементов для просмотра равно 3, получили выход за границу массива.
Возможно, ChatGPT не нашёл данную ошибку, так как она не распространена, и у него просто не было нужной информации для обучения. Правда это не значит, что такую ошибку нельзя допустить, и её не нужно искать.
Cлучаются и промахи, когда ChatGPT говорит об ошибке, которой нет.
Диагностика V3178. На этом корректном коде ChatGPT смог найти ошибку, которой нет. По его словам, с помощью Console.WriteLine пытаются писать в файл, что является проблемой. Однако ничего такого здесь нет.
Синтетические уязвимости
PVS‑Studio также умеет проверять код на наличие потенциальных уязвимостей. А умеет ли ChatGPT? Попросим его найти уязвимость SQL‑инъекция.Диагностика V5608. И бот справился. Он верно распознал уязвимость и подсказал, что для защиты от SQL injection нужно использовать параметризованные запросы.
Теперь попросим проанализировать код, в котором уже защитились от уязвимости.
ChatGPT посчитал, что этот код безопасен, и это действительно так. Вот только он не всегда правильно обрабатывает корректный код. Рассмотрим пример LDAP injection, в котором уже защитились от этой уязвимости.
Диагностика V5620. Хм, ChatGPT нашёл атаку типа LDAP injection. По его мнению, пользовательский ввод никак не проверяется и не кодируется. Однако мы вызвали метод Encoder.LdapFilterEncode, который как раз кодирует внешние данные.
Реальные ошибки и уязвимости
Весь код, который мы просили ИИ посмотреть, являлся синтетическим. Что же будет на реальном проекте? В прошлом году мы выпускали статью про XXE уязвимости: «Уязвимости из‑за обработки XML‑файлов: XXE в C# приложениях в теории и на практике«. В ней был пример воспроизводимой уязвимости на проекте BlogEngine.NET, которую обнаруживает PVS‑Studio.Возьмём код, указанный в данной статье, и попросим найти ошибку.
public XMLRPCRequest(HttpContext input)
{
var inputXml = ParseRequest(input);
// LogMetaWeblogCall(inputXml);
this.LoadXmlRequest(inputXml); // Loads Method Call
// and Associated Variables
}
private static string ParseRequest(HttpContext context)
{
var buffer = new byte[context.Request.InputStream.Length];
context.Request.InputStream.Position = 0;
context.Request.InputStream.Read(buffer, 0, buffer.Length);
return Encoding.UTF8.GetString(buffer);
}
private void LoadXmlRequest(string xml)
{
var request = new XmlDocument();
try
{
if (!(xml.StartsWith("<?xml") || xml.StartsWith("<method")))
{
xml = xml.Substring(xml.IndexOf("<?xml"));
}
request.LoadXml(xml);
}
catch (Exception ex)
{
throw new MetaWeblogException("01",
$"Invalid XMLRPC Request. ({ex.Message})");
}
....
}
На просьбу найти в данном коде уязвимость,
Увы, размерность массива buffer в точности такая, какая и требуется для содержимого потока. В теории возможна ситуация получения исключения System.OverflowException при выделении памяти под массив, если длина потока будет больше максимальной размерности массива. На практике при попытке получения входного потока будет выброшено исключение System.Web.HttpException с сообщением «Maximum request length exceeded». Далее это исключение будет определённым образом обработано. Выделения памяти под массив не произойдёт.
После этого мы задали вопрос про существование других уязвимостей в данном коде.
На этот вопрос бот дал довольно общий ответ о том, что в программах возможны уязвимости и нужно регулярно проводить анализ безопасности для выявления потенциальных уязвимостей. Хм, не могу не согласиться, но это не то, что ожидалось.
При этом PVS‑Studio выдаст на данный код следующее предупреждение:
V5614 [CWE-611, OWASP-5.5.2] Potential XXE vulnerability inside method. Insecure XML parser is used to process potentially tainted data from the first argument: 'inputXml'. BlogEngine.Core XMLRPCRequest.cs 41
Стоит сказать, что у моего коллеги ChatGPT всё‑таки смог найти эту уязвимость. Сказывается непостоянность его ответов.
Примечание. Кстати, результат, который может быть получен только с некоторой вероятностью, не очень подходит для инструментария программиста. Например, представьте, вы чуть поправили код и предупреждение исчезло. Что это значит? Вы исправили ошибку? Или просто теперь о ней не сообщают?
А как бот справляется с ошибками copy‑paste? Пример ошибки из статьи, где мы с помощью PVS‑Studio искали ошибки в веб‑проектах, использующих ASP.NET Core. На 7 строке того рейтинга из статьи как раз была copy‑paste ошибка из проекта Piranha CMS.
public override async Task InitializeAsync()
{
using (var api = CreateApi())
{
....
// Add archive
var blog = await BlogArchive.CreateAsync(api);
blog.Id = BLOG_ID;
blog.SiteId = SITE_ID;
blog.Title = "Blog";
blog.EnableComments = true;
blog.Published = DateTime.Now;
await api.Pages.SaveAsync(blog);
var news = await BlogArchive.CreateAsync(api);
news.Id = NEWS_ID;
news.SiteId = SITE_ID;
news.Title = "News";
blog.EnableComments = true; // <=
news.Published = DateTime.Now;
await api.Pages.SaveAsync(news);
....
}
}
Немного мыслей
Перед выводом хочется добавить немного размышлений.При использовании подобных систем искусственного интеллекта возникает вопрос сохранности исходного кода, ведь его придётся куда‑то отправлять. Сегодня ты отправляешь свой код ИИ, а завтра этот код кто‑то получает в качестве ответа на свой вопрос. Со всеми уязвимостями твоего проекта или продукта компании. Уже известно, что сотрудников Amazon и Microsoft попросили не делиться с ChatGPT конфиденциальной информацией.
Стоит помнить, что всю информацию, которую выдаёт любой искусственный интеллект в качестве ответа, нужно проверять. Хорошо, когда вы разбираетесь в теме и можете оценить корректность выдаваемой информации. Но может быть и так, что человек не разбирается в вопросе, и ИИ выдаёт неправильный ответ. Если пользователь не станет проверять полученную информацию, то это может привести к различным ошибкам и проблемам, а может и человеческим жертвам (в различных областях).
Несмотря на вышесказанное, я был сильно удивлён возможностями ChatGPT. Мы один раз в шутку попросили найти его ошибку в первом примере статьи и выдать ответ в формате SARIF. Не описать словами наше удивление, когда он это правда сделал.
Я думаю, что подобные модели искусственного интеллекта могут дополнить статический анализ, но никак не заменить его. ИИ можно было бы использовать для:
- выявления определённых паттернов ошибок в коде;
- повысить точность анализа за счёт обнаружения и откидывания ложных срабатываний.
Я считаю, что ChatGPT это неплохое подспорье, которое может стать отправной точкой для дальнейшей работы. Например, составить текст для ответа клиенту, накидать небольшую заметку или даже кусок для этой статьи.
Вывод
Конечно, данное сравнение было сделано скорее ради человеческого любопытства и забавы, а не реального сравнения статического анализатора PVS‑Studio и ChatGPT. Понятно, что ChatGPT не обладает полной информацией о программе. Статическому анализу с этим проще, у него есть более полное представление кода и различная семантическая информация. Можно сказать, что статический анализатор просто обладает большими знаниями о происходящем. Это помогает ему находить довольно сложные проблемы, которые не всегда видны с первого взгляда.Плюс поиск ошибок — это не только сам анализ и выдача сообщения, а ещё и идущая в комплекте инфраструктура. Плагины для IDE с удобной навигацией и фильтрацией, встраивание в CI, поддержка игровых движков, лёгкое использование в проектах с legacy и многое другое, идёт в комплекте с анализатором. Боту, например, тяжело сказать, что он ошибся (он ещё может не соглашаться), а в плагине можно просто отметить предупреждение как ложное.
Спасибо за прочтение, надеюсь, вы утолили свой интерес. Всем интересующимся данной темой предлагаю также почитать статью «Использование машинного обучения в статическом анализе исходного кода программ» про нюансы совмещения искусственного интеллекта и методологии статического анализа. На данный момент приведённые в ней аргументы всё ещё в силе. ИИ для поиска ошибок и уязвимостей выглядит пока больше как игрушка в сравнении с классическими статическими анализаторами кода.
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Artem Rovenskii. Is ChatGPT good enough at spotting bugs in code?Goodbye to all the readers of the article! Thank you for taking the time to read this. I hope the information provided was helpful and informative. If you have any further questions, feel free to ask. Have a great day!
— ChatGPT
Хорошо ли ChatGPT ищет ошибки в коде?
Нейросети всё больше вливаются в привычный мир, пытаясь упростить нам жизнь. Тот же ChatGPT вызвал бурю обсуждений в интернете. Чат бот способен писать тексты, код, рефераты и песни. Он...
habr.com