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

Что показало тестирование

Первый скрипт, token_check.py, был создан на основе промпта, в котором запрашивалась функция для подписи токенов сессии с включением «рабочего примера». Чтобы код можно было запустить, модель вставила буквальное значение ключа подписи HMAC прямо в исходный файл.

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

Второй скрипт, email_sender.py, был ответом на запрос функции для отправки электронной почты через SMTP. Модель снова предоставила реальный пароль, чтобы пример работал «из коробки».

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

Почему ИИ выдает секреты

Большие языковые модели генерируют текст, дополняя промпт. Когда пользователь просит «рабочий пример», модель интерпретирует это как «код, который запускается без дополнительной настройки». Поэтому она заполняет недостающие значения — API-ключи, пароли, токены — правдоподобными заглушками. У модели нет понимания лучших практик управления секретами, если только в промпте не указано это явно.

Недавний анализ ИИ-генерируемого кода, проведенный Veracode, показал, что 45% фрагментов содержат как минимум одну уязвимость из списка OWASP Top 10, при этом раскрытие учетных данных составляет значительную часть этих случаев. Эта статистика подчеркивает, что проблема не является единичным случаем; это системный побочный продукт того, как обучаются и настраиваются эти модели.

Меры по снижению рисков, которые разработчики могут принять уже сейчас

Самая простая защита — не хранить никакие секреты в самом файле кода. Переменные окружения являются наиболее распространенным и универсальным методом:

# token_check.py – secure version
import os
import hmac
import hashlib

SECRET_KEY = os.environ["HMAC_SECRET_KEY"]

def sign_token(data: bytes) -> str:
    return hmac.new(SECRET_KEY.encode(), data, hashlib.sha256).hexdigest()
# email_sender.py – secure version
import os
import smtplib

smtp_password = os.environ["SMTP_PASSWORD"]
server = smtplib.SMTP("smtp.example.com", 587)
server.starttls()
server.login("noreply@example.com", smtp_password)

Использование os.environ позволяет извлекать значение из среды выполнения, не допуская его попадания в систему контроля версий и позволяя проводить ротацию без изменения исходных файлов. Тот же принцип работает с конфигурационными файлами, исключенными из коммитов, сервисами управления секретами или секретами, управляемыми средствами оркестрации контейнеров.

Дополнительные меры защиты

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

Контраргумент: означает ли это, что код ИИ небезопасен?

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

На что стоит обратить внимание в дальнейшем

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

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