Проверка безопасности кода, написанного 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, что разрешают политики, кто реально может читать и писатьСводная таблица с оценкой риска
Авторизация на сервереПопытки открыть и изменить чужие записи от имени обычного пользователяКонкретные адреса и запросы, которые пропускают чужого
ЗависимостиСуществование каждого пакета, известные уязвимости, заброшенные библиотекиСписок замен
Входные данныеЗагрузка файлов, формы, параметры, которые попадают в запросы к базеМеста, где пользовательский ввод попадает в базу без проверки

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

Что можно сделать самостоятельно до проверки

  1. Откройте сайт, нажмите F12 и поищите в исходниках слова key, secret, token. Всё найденное, кроме публичного ключа Supabase, считайте утёкшим.
  2. В панели Supabase откройте список таблиц и посмотрите, у каких из них нет отметки RLS. Каждая такая таблица открыта.
  3. Зайдите под вторым пользователем и попробуйте открыть адрес чужой записи, подменив номер.
  4. Если сработал хотя бы один пункт, не выкладывайте новые функции, пока это не закрыто: каждая новая таблица наследует ту же ошибку.

Частые вопросы

Безопасен ли публичный ключ Supabase в браузере?

Да, если на каждой таблице включён Row Level Security и политики настроены так, что пользователь видит только свои строки. Без RLS тот же ключ даёт чтение и запись всей таблицы. Служебный ключ service_role в браузере не безопасен никогда.

AI-ассистент сам не проверяет безопасность?

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

Что такое IDOR простыми словами?

Это когда запись открывается по номеру, а сервер не проверяет, ваша ли она. Подставили соседний номер и увидели чужой заказ, счёт или профиль. В AI-коде это частая ошибка, потому что в интерфейсе ссылка на чужую запись просто не показывается, и кажется, что этого достаточно.

Нужен ли доступ к рабочей базе данных?

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

Сколько времени занимает исправление?

Обычно это не переписывание. Политики RLS, перенос ключей на сервер и проверка владельца записи в API закрываются точечно. Срок зависит от количества таблиц и мест, где сервер доверяет интерфейсу, после проверки он становится понятен по пунктам.

С чего начать

Пришлите адрес приложения и скажите, на чём оно сделано: Lovable, Bolt, Cursor или другое. Первые четыре проверки из списка выше покажут, есть ли срочное.

Написать мне

По теме: Аудит AI-кода, Проект на вайб-кодинге, Vibe coding: Lovable

SLAtech LTD