Проверка безопасности кода, написанного AI
Код, который сгенерировал AI, обычно работает. Уязвим он не потому, что сломан, а потому, что модель решает задачу «чтобы заработало», а безопасность в этой задаче не была условием.
Кратко
Большинство дыр в AI-коде одного происхождения: проверка прав сделана в интерфейсе, а не на сервере. Отсюда ключи в коде браузера, таблицы Supabase без политик RLS и чужие записи, доступные по номеру в адресе. Проверка начинается с четырёх вопросов: где лежат секреты, кто может читать каждую таблицу, проверяет ли сервер владельца записи и существуют ли на самом деле все подключённые пакеты. Ответы на них дают список, который можно закрыть за дни, а не переписывание.
Почему AI пишет уязвимый код
Модель отвечает на запрос. Если в запросе сказано «сделай вход и список заказов», она сделает вход и список заказов. То, что пользователь не должен видеть чужие заказы, в запросе не сказано, и в коде этого часто тоже нет.
Это измерено. Исследование Veracode проверило больше сотни моделей на одних и тех же задачах: в 45% случаев модель выбирала небезопасный вариант, хотя безопасный был доступен, и новые модели в этом не лучше старых. В исследовании Стэнфорда участники с AI-ассистентом писали менее безопасный код, чем без него, и при этом чаще считали его безопасным. Вторая половина этого вывода важнее первой.
Уязвимость не видна в демо. Приложение, в котором любой может прочитать все записи, в демонстрации выглядит точно так же, как приложение, где этого сделать нельзя. Разница видна только тому, кто специально пробует.
Четыре места, где искать в первую очередь
1. Секреты в браузерном коде
Всё, что попало во фронтенд-код, доступно любому посетителю через инструменты разработчика. Ключ платёжной системы, ключ OpenAI или служебный ключ базы данных в таком коде означает, что ключ уже опубликован. По данным GitGuardian, на публичный GitHub за год утекают миллионы секретов, и большая часть утёкших ключей годами остаётся рабочей: их никто не отзывает.
2. Таблицы без политик доступа
В Supabase публичный ключ (anon, теперь publishable) по замыслу можно показывать в браузере. Он безопасен только в том случае, если на каждой таблице включён Row Level Security и настроены политики. Документация Supabase говорит об этом прямо: таблица в открытой схеме без RLS доступна на чтение и запись любой роли, у которой есть на неё права. Служебный ключ (service_role, теперь secret) обходит все политики и не должен попадать ни в браузер, ни в репозиторий.
Это не теория. По уязвимости CVE-2025-48757 исследователь проверил 1645 проектов, сделанных в Lovable, и у 170 из них нашёл недостаточные политики RLS: через них читались персональные данные, ключи сторонних сервисов и платёжные данные. Lovable оспаривает эту CVE и считает, что ответственность за данные лежит на владельце каждого проекта. Для владельца проекта вывод одинаков при любой позиции платформы: проверять всё равно придётся самому.
3. Права проверяются только в интерфейсе
Кнопка «удалить» скрыта у тех, кому удалять нельзя, но сам запрос на удаление сервер выполнит от любого. Или страница заказа открывается по номеру /orders/1043, и если подставить 1044, откроется чужой заказ. Это называется IDOR, и OWASP ставит нарушение контроля доступа на первое место в своём списке рисков: в проверенных приложениях оно встречается в той или иной форме почти всегда.
4. Пакеты, которых не существует
Модели иногда подключают библиотеку с правдоподобным именем, которой на самом деле нет. Исследование, представленное на USENIX Security, насчитало больше двухсот тысяч уникальных выдуманных имён пакетов, у открытых моделей доля таких ссылок доходила до пятой части. Злоумышленнику достаточно зарегистрировать это имя и выложить пакет с вредоносным кодом. Такой приём называется slopsquatting.
Что входит в проверку
| Что проверяем | Как | Что получаете |
| Секреты | Поиск ключей во фронтенд-коде, в истории репозитория и в сборке | Список ключей, которые надо отозвать, и куда их перенести |
| Доступ к данным | Каждая таблица: включён ли RLS, что разрешают политики, кто реально может читать и писать | Сводная таблица с оценкой риска |
| Авторизация на сервере | Попытки открыть и изменить чужие записи от имени обычного пользователя | Конкретные адреса и запросы, которые пропускают чужого |
| Зависимости | Существование каждого пакета, известные уязвимости, заброшенные библиотеки | Список замен |
| Входные данные | Загрузка файлов, формы, параметры, которые попадают в запросы к базе | Места, где пользовательский ввод попадает в базу без проверки |
Проверка проводится на копии или с правами обычного пользователя. Ключи от рабочей базы, пароли и строки подключения к ней не нужны и не запрашиваются.
Что можно сделать самостоятельно до проверки
- Откройте сайт, нажмите F12 и поищите в исходниках слова
key, secret, token. Всё найденное, кроме публичного ключа Supabase, считайте утёкшим.
- В панели Supabase откройте список таблиц и посмотрите, у каких из них нет отметки RLS. Каждая такая таблица открыта.
- Зайдите под вторым пользователем и попробуйте открыть адрес чужой записи, подменив номер.
- Если сработал хотя бы один пункт, не выкладывайте новые функции, пока это не закрыто: каждая новая таблица наследует ту же ошибку.
Частые вопросы
Безопасен ли публичный ключ Supabase в браузере?
Да, если на каждой таблице включён Row Level Security и политики настроены так, что пользователь видит только свои строки. Без RLS тот же ключ даёт чтение и запись всей таблицы. Служебный ключ service_role в браузере не безопасен никогда.
AI-ассистент сам не проверяет безопасность?
Проверяет то, о чём его попросили. Исследования показывают, что без явного требования модель часто выбирает небезопасный вариант, а разработчик с ассистентом склонен больше доверять результату. Поэтому проверка нужна отдельная и с другой целью: не построить, а сломать.
Что такое IDOR простыми словами?
Это когда запись открывается по номеру, а сервер не проверяет, ваша ли она. Подставили соседний номер и увидели чужой заказ, счёт или профиль. В AI-коде это частая ошибка, потому что в интерфейсе ссылка на чужую запись просто не показывается, и кажется, что этого достаточно.
Нужен ли доступ к рабочей базе данных?
Нет. Мы работаем с копией или с правами обычного пользователя, как это сделал бы посторонний. Ключи, пароли и строки подключения к рабочей среде для проверки не нужны.
Сколько времени занимает исправление?
Обычно это не переписывание. Политики RLS, перенос ключей на сервер и проверка владельца записи в API закрываются точечно. Срок зависит от количества таблиц и мест, где сервер доверяет интерфейсу, после проверки он становится понятен по пунктам.
SLAtech LTD