ИИ и безопасность

Код, написанный ИИ, и уязвимости: почему Copilot не делает разработку безопасной сама по себе

GitHub Copilot, ChatGPT и десятки аналогичных инструментов за последние годы прочно вошли в повседневную работу разработчиков. Скорость написания кода выросла заметно, и это не маркетинговое преувеличение: мои собственные наблюдения на проектах, где я консультирую команды разработки по безопасности, совпадают с тем, что показывают независимые исследования. Проблема не в скорости. Проблема в качестве и безопасности кода, который эта скорость производит.

Что показывают исследования

Исследование, проведённое группой учёных из Стэнфорда в 2023 году, стало одним из первых, количественно подтвердивших интуицию многих специалистов по безопасности: разработчики, использующие ИИ-ассистента для написания кода, в среднем чаще допускали уязвимости по сравнению с теми, кто писал код самостоятельно. При этом те же самые разработчики, использовавшие ИИ, были более уверены в безопасности своего кода, чем контрольная группа, писавшая без ассистента.

Это сочетание, больше ошибок при большей уверенности, особенно опасно с точки зрения организации процесса разработки, потому что уверенность разработчика напрямую влияет на то, насколько тщательно он проверяет собственный код перед отправкой на ревью. Разработчик, который чувствует себя уверенно, реже перепроверяет логику безопасности вручную, полагаясь на то, что инструмент, сгенерировавший код, уже сделал это за него.

Почему генеративные модели пишут небезопасный код

Языковые модели обучаются на огромных массивах публичного кода, значительная часть которого взята из открытых репозиториев, форумов вроде Stack Overflow, учебных материалов. Проблема в том, что немалая часть этого обучающего материала сама по себе содержит устаревшие или небезопасные практики: код из старых туториалов, написанный до появления современных стандартов безопасности, ответы на форумах, оптимизированные для «быстрого решения проблемы», не для продакшен-качества.

Модель не «знает», что конкретный паттерн кода небезопасен, в том смысле, в каком это знает опытный инженер с пониманием класса уязвимостей вроде OWASP Top 10. Она воспроизводит статистически вероятное продолжение на основе того, что видела в обучающих данных, и если небезопасный паттерн встречался в этих данных достаточно часто, модель с высокой вероятностью его воспроизведёт, причём стилистически грамотно и уверенно.

Классические примеры, которые регулярно всплывают в сгенерированном коде: конкатенация пользовательского ввода в SQL-запрос вместо параметризованных запросов (классическая уязвимость SQL-инъекции, известная десятилетиями), хранение секретов и ключей API прямо в коде вместо переменных окружения или менеджера секретов, отсутствие валидации входных данных там, где она критична, использование устаревших криптографических алгоритмов, которые когда-то были стандартом, но давно признаны ненадёжными.

Генеративная модель не проектировалась как инструмент обеспечения безопасности кода. Она проектировалась как инструмент, предсказывающий правдоподобное продолжение текста. То, что часть предсказанного кода оказывается рабочей и даже безопасной, приятный побочный эффект масштаба обучающих данных. Целенаправленная инженерия безопасности тут ни при чём.

Отдельная проблема: сгенерированные зависимости

Относительно новый и менее очевидный риск связан с тем, что модели иногда «галлюцинируют» названия несуществующих библиотек или пакетов, выглядящих правдоподобно. Исследователи безопасности зафиксировали феномен, который получил название slopsquatting: злоумышленники регистрируют пакеты с именами, которые модели статистически склонны «придумывать» в своих ответах, и размещают в них вредоносный код. Разработчик, доверяющий сгенерированному коду и устанавливающий предложенную моделью зависимость без проверки её реального существования и репутации, рискует напрямую внедрить вредоносный код в свой проект.

Почему это не повод отказываться от инструмента

Было бы неправильным выводом из всего сказанного запретить использование ИИ-ассистентов в разработке. Производительность, которую они дают, реальна, и компания, отказавшаяся от этого инструмента по соображениям безопасности, просто проиграет в скорости разработки конкурентам, которые научились использовать его правильно. Задача не в запрете. Задача в том, чтобы адаптировать процесс разработки к новой реальности: значительная часть кода пишется теперь с помощью инструмента, не человеком напрямую.

Как адаптировать процесс разработки

Код-ревью должно оставаться обязательным для любого кода, вне зависимости от того, написан он человеком, ИИ-ассистентом или получен в результате их совместной работы. Отношение к сгенерированному коду разумно строить по аналогии с кодом junior-разработчика: потенциально рабочий, но требующий внимательной проверки опытным специалистом, особенно в части логики безопасности.

Автоматизированное сканирование кода на уязвимости (SAST, статический анализ) должно быть встроено в CI/CD конвейер как обязательный шаг, не рекомендательный, именно потому что объём генерируемого кода растёт быстрее, чем способность команды вручную просматривать каждую строчку с должным вниманием.

Проверка зависимостей, добавляемых в проект (включая те, что предложены ИИ-ассистентом), на реальное существование, репутацию и известные уязвимости должна стать стандартной практикой. Доверие на слово инструменту, который технически способен «придумать» несуществующий, но правдоподобно звучащий пакет, тут не подходит.

Обучение команды разработки конкретно тому, какие классы уязвимостей чаще всего проскальзывают в сгенерированном коде, помогает разработчикам сфокусировать внимание при ревью именно на тех местах, где риск статистически выше. Проверка всего кода с одинаковым, размазанным вниманием работает хуже.

Специально выделенное время на углублённое ревью безопасности для кода, обрабатывающего аутентификацию, авторизацию, платежи и персональные данные, оправдано вне зависимости от того, кто (или что) этот код написал, но становится особенно важным с учётом того, что уверенность разработчика в качестве сгенерированного кода статистически завышена по сравнению с реальным качеством.

Итоговая мысль

ИИ-ассистенты меняют экономику разработки программного обеспечения, и это изменение необратимо. Вопрос не в том, использовать их или нет, а в том, успевает ли процесс обеспечения безопасности разработки адаптироваться к новой скорости и новому профилю ошибок. Команда, которая просто добавила Copilot в рабочий процесс, ничего не поменяв в практике ревью и тестирования, с высокой вероятностью пишет код быстрее, но не безопаснее. Иногда даже опаснее прежнего.

Разработка в компании активно использует ИИ-ассистентов для написания кода? DevSecOps-консалтинг помогает встроить проверки безопасности в процесс, который уже изменился быстрее, чем политика ИБ.