Почему ChatGPT пишет код с уязвимостями и как это исправить: наблюдение белого хакера
Всем привет! Я Артемий Богданов, занимаюсь практической безопасностью и работаю в Start X (ex-Антифишинг). А в прошлом находил уязвимости в Uber, Yahoo и ВКонтакте, занимал призовые места в конкурсах PHDays, NeoQUEST и других CTF.
Как-то раз для одной отраслевой конференции по кибербезопасности мне понадобилось сделать обучающее видео о том, как хакер может взломать уязвимое веб-приложение.
Для этого я решил написать приложение по доставке еды, добавить туда уязвимости и на видео показать, как его можно взломать. Времени было впритык, поэтому план был простой: использовать ChatGPT, чтобы написать код, а потом самостоятельно вставить в него ошибки. Но что-то пошло не так.
Какое приложение мне было нужно
Итак, чтобы показать, как происходит взлом, я решил создать простое приложение для заказа еды.
Принцип работы такой: клиент вводит контактные данные, адрес доставки, телефон, затем выбирает товары из меню, добавляет в корзину и делает заказ:
Клиенту сообщают, что заказ принят, подтверждают имя и адрес и обещают перезвонить:
Я хотел, чтобы у взломщика было два варианта действий.
Первый — через небезопасную десериализацию пользовательских данных. Второй — через цепочку уязвимостей: эксплуатация XSS и получение доступа в административную часть приложения → произвольное чтение файлов → восстановление PIN-кода к консоли Python.
Расскажу подробнее о первом способе, это будет важно для дальнейшей истории.
В приложении можно указать адрес телефона и сделать заказ. Пользовательские данные сохраняются в куки в некотором сериализованном формате. Мне хотелось сделать неочевидный ход, поэтому вместо часто встречающегося формата JSON я решил использовать YAML для записи пользовательских данных в куки. Это должно было стать подсказкой для хакера — возможно, в приложении что-то не так.
Если злоумышленник специальным образом составит yaml-эксплоит, то сможет выполнить произвольный код на Python и, например, откроет back-connect shell для более удобной постэксплуатации. В итоге злоумышленник после нескольких действий получит доступ к серверу.
Уязвимости, в том числе эту, я собирался вставить сам, а вот для того, чтобы сделать приложение, нанял ChatGPT.
Какие промпты я давал ChatGPT
У меня была четкая идея, как технически должно работать приложение, поэтому я планировал итеративно посылать промпты в чат и получать необходимые мне фрагменты кода.
Так выглядел первый промпт
После первой порции кода от ChatGPT приложение писало «Добро пожаловать в наш сервис доставки еды». Также в нем был базовый функционал заказа:
После этого я попросил сделать другой дизайн кнопок и объектов, использовать Bootstrap в качестве CSS-фреймворка, добавить форму заказа, меню и другие опции.
Сперва ChatGPT решил обойтись советом вместо кода:
Тогда я попросил настойчивее, но разметку с использованием элементов из Bootstrap все равно не получил:
На третий раз получилось:
Картинки, кстати, пришлось искать самому — ChatGPT больше не рекомендует другие нейронные сети для решения конкретных задач, даже если попросить совет напрямую.
Где появились уязвимости
Я хотел добавить в приложение уязвимость, которая позволила бы эксплуатировать небезопасную десериализацию пользовательских данных. Для этого нужно, чтобы данные пользователя сохранялись в куках.
Я попросил об этом ChatGPT и сделал упор на том, чтобы данные сохранялись в YAML:
В ответ ChatGPT привел пример уязвимого кода, в котором есть возможность для проникновения:
Строка, выделенная серым, позволяет пользователю вставить свой код на сервере, заменив в кукис исходный параметр на свой специальный:
Ну что — спасибо ChatGPT за то, что выполнил часть работы за меня. А если серьезно, какие можно делать выводы?
Их несколько:
0. Не доверяйте ChatGPT, он бездушная машина.
Нейросети уже достаточно крутые, чтобы писать какие-то фрагменты кода. ChatGPT помог мне с кнопками и формой для заказа и смог под моим руководством привести внешний вид приложения к адекватному виду.
При этом человек, далекий от разработки, вряд ли сможет создать полноценное приложение с помощью ChatGPT — для этого нужно быть оператором нейросети, учитывать контекст, исправлять код дополнительными промптами. При этом навык ревью при работе с нейросетью не менее важен, чем навык разработки.
Но главная проблема — нужно разбираться не только в коде, но и владеть навыками разработки безопасного кода и security code review. Без них сложно заметить, что ChatGPT допустил ошибку и добавил в код уязвимость.
Чтобы проводить security code review, нужно проходить полноценное обучение — причем разработчикам любого уровня.
У джунов часто нет знаний о безопасной разработке из-за небольшого опыта в отрасли.
У мидлов и сеньоров больше опыта, квалификации и уверенности в себе — они регулярно находят решения для множества сложных задач. Но в случае с безопасной разработкой их, на первый взгляд, правильные решения могут быть неверными и лишь усложнят выявление или эксплуатацию уязвимости, но не избавят от нее.
Обучение безопасной разработке важно не только для отдельных компаний, но и в целом для отрасли. Нейросети пишут код не просто так — они обучаются, читая код других разработчиков. Это значит, что все ошибки, которые допускают разработчики, влияют на код, который выдает нейросеть.
При этом Chat GPT уже знает, что такое безопасный код. Если специально попросить его написать приложение с уязвимостями, то он предупредит, что так делать не стоит, и объяснит почему.
В конце покажу то самое обучающее видео, для которого я писал приложение: