Supabase row level security (RLS) - это встроенный в Postgres механизм, который решает, какие строки таблицы видит конкретный пользователь. Проблема в том, что Lovable, Cursor, Bolt и другие AI-инструменты регулярно создают таблицы в Supabase вообще…
10+ лет в маркетинге, 300+ клиентских проектов: сайты, реклама, боты. Создатель GoBanana (228K+ пользователей, 11.6 млн ₽ выручки) и VibeCoderz. Делаю AI-продукты сам через Claude Code, Cursor, Windsurf и консультирую тех, кто хочет так же.
Об авторе →Claude Code: новый CLI-агент от Anthropic
Anthropic выпустила Claude Code — терминальный AI-агент для разработчиков. Инструмент работает прямо в командной строке и умеет писать, редактировать и запускать код.
Zcode AI: Полный гид по визуальному интерфейсу для Claude Code и AI-агентов
Узнайте, как использовать Zcode для управления Claude Code, Gemini и Codex в едином GUI. Настройка провайдеров, MCP-серверов и визуальный вайбкодинг.
YouTube-канал с монетизацией из любой точки мира: Пошаговый гайд 2026
Инструкция по созданию YouTube-канала: обход блокировок SMS, настройка расширенных функций через виртуальные номера и правила безопасности для монетизации.
Windsurf Code Maps: Как глубоко понимать архитектуру проекта перед написанием кода
Полный гайд по Windsurf Code Maps, модели Sway 1.5 и Sway Grep. Узнайте, как визуализировать архитектуру кода и ускорить разработку в 13 раз.
Vk Fast Cash Strategy
Аудитория ВКонтакте — это те же люди, что и в Instagram, но 'социальный контракт' площадки другой. Если Instagram — это 'дорогой ресторан' с демонстрацией успеха, то VK — это 'душевная шашлычная'. Здесь не работает глянцевый 'успешный успех
Supabase row level security (RLS) - это встроенный в Postgres механизм, который решает, какие строки таблицы видит конкретный пользователь. Проблема в том, что Lovable, Cursor, Bolt и другие AI-инструменты регулярно создают таблицы в Supabase вообще без RLS-политик или с политикой вида USING (true), которая пропускает всех. Ниже разберем, откуда берется эта ошибка, что показал CVE-2025-48757, и дадим готовый промпт для аудита схемы.
RLS в Supabase выключен по умолчанию для новых таблиц, а анонимный ключ (anon key) специально устроен так, чтобы быть публичным. Без явных политик любая таблица в схеме public читается и пишется кем угодно через автоматический REST API. По данным анализа Lovable-проектов, 10,3% из 1 645 изученных приложений содержали таблицы, открытые для чтения без аутентификации. В статье: механика уязвимости, разбор CVE-2025-48757, чек-лист проверки и промпт для аудита.

Row Level Security - это правило на уровне базы данных, а не на уровне интерфейса приложения. Оно решает, какие строки таблицы вернутся конкретному пользователю при запросе, независимо от того, что рисует фронтенд.
Row Level Security в Postgres работает как привратник между базой и любым запросом. Каждый раз, когда клиент дергает REST API или JS SDK Supabase, движок проверяет политики для этой таблицы и решает, какие строки показать. Если политики нет, а RLS включен, Postgres по умолчанию не отдаст ничего. Если же RLS выключен вообще, привратника просто нет.
Тут и кроется путаница у новичков. Supabase автоматически генерирует REST API поверх каждой таблицы Postgres. Это удобно: не нужно писать бэкенд для CRUD-операций. Но именно поэтому таблица без RLS доступна напрямую из браузера любому, у кого есть anon key. А anon key видно в исходном коде любого сайта на Supabase, это не секрет и не должно им быть. Секретом должна быть логика доступа, то есть сами политики.
AI-модели оптимизируют код под то, чтобы он запустился и прошел миграцию, а не под правильность авторизации. Схема применяется, приложение работает в деве, а дыра в безопасности остается невидимой до первой атаки.
Языковая модель генерирует SQL-миграцию, которая создает таблицу, и на этом задача для нее формально выполнена: таблица есть, поля есть, приложение стартует. RLS для новых таблиц в Supabase по умолчанию выключен, будь то создание через SQL Editor или через Table Editor. Модель не получает сигнала о том, что забыла критичный шаг, потому что приложение прекрасно работает и без политик, ведь без RLS доступ вообще ничем не ограничен.
Вторая частая причина - несовпадение типов данных. В одном из разборов RLS-политик авторы отмечают: если owner_id в таблице хранится как bigint, а auth.uid() возвращает uuid, сравнение в политике молча не сработает, и строки не отдадутся никому либо отдадутся всем, в зависимости от логики условия. AI-инструменты типа Cursor часто копируют такой паттерн из старого кода проекта, не проверяя совместимость типов.
Третья причина конкретно для Lovable: сама платформа получила встроенный security-сканер только в версии 2.0, 24 апреля 2025 года, спустя три недели после первого раскрытия уязвимости. И даже этот сканер проверяет только сам факт наличия RLS и политики, но не анализирует, реально ли политика ограничивает доступ. Таблица с политикой USING (true) формально проходит проверку зеленой галочкой, оставаясь полностью открытой.

Исследователь Мэтт Палмер уведомил Lovable в марте 2025 года и опубликовал разбор 29 мая 2025-го. Из 1 645 проанализированных проектов на Lovable у 170 (10,3%) нашлись таблицы Supabase, читаемые кем угодно через публичный anon key.
Палмер проверял реальные production-приложения, собранные на Lovable, и искал таблицы Supabase, доступные напрямую через REST API без авторизации. Итог: 303 открытых эндпоинта в 170 проектах. Через них можно было вытянуть email пользователей, платежные данные, приватные сообщения, токены доступа. Это не баг конкретно в коде Lovable, а системный результат того, что клиент напрямую стучится в базу через публичный ключ, а RLS остается единственным барьером и часто отсутствует.
Отдельный кейс из того же периода, известный как утечка Moltbook, показывает масштаб риска нагляднее любой цифры. Через некорректно настроенную базу Supabase без row level security за первые три дня после запуска утекли 1,5 миллиона токенов аутентификации API и 35 000 email-адресов. Проект даже не успел набрать заметную аудиторию, а данные уже оказались снаружи.

Максим: «Веб-версию GoBanana мы собрали за 3 часа после выхода новой модели, весь продукт занял 6-8 часов и принес 12 миллионов рублей. Но скорость не отменяет проверку. Перед тем как показать продукт первому пользователю, всегда открываем дашборд Supabase и смотрим, у каких таблиц RLS выключен.»
В открытых Supabase-таблицах чаще всего находят email, номера заказов, платежные данные и служебные токены. Больше 50 таблиц с названиями вроде payments или orders в одном из аудитов принимали запись без аутентификации вообще.
Согласно чек-листу безопасности Supabase, среди найденных в открытом доступе данных встречались номера банковских счетов, коды доступа пациентов в медицинских приложениях, сохраненные OAuth-токены и логи админ-панелей. Причем речь не только о чтении: часть таблиц принимала анонимную запись, то есть любой посетитель мог не просто прочитать чужие заказы, а создать или изменить их.

| Что нашли | Где встречается | Последствие |
|---|---|---|
| Email и телефоны пользователей | Таблицы users, profiles | Спам, фишинг, утечка персональных данных |
| Платежные данные, номера заказов | Таблицы payments, orders | Финансовое мошенничество |
| API и OAuth токены | Таблицы integrations, tokens | Доступ к сторонним сервисам от имени жертвы |
| Приватные сообщения и файлы | Таблицы messages, storage | Репутационный ущерб, утечка переписки |
Отдельное исследование ста вайбкод-приложений нашло похожую картину: 41% содержали открытые секреты или API-ключи в коде, у 21% вообще не было аутентификации на API-эндпоинтах, а у 12% ключи Supabase читались прямо из JS-бандла на фронтенде. Это не редкие исключения, а типичный результат генерации кода без отдельного слоя проверки безопасности.
Один SQL-запрос в редакторе Supabase показывает все таблицы схемы public без включенной защиты. Если список не пустой, приложение открыто для чужих запросов прямо сейчас.
Заходите в SQL Editor внутри проекта Supabase и выполняете:
SELECT tablename
FROM pg_tables
WHERE schemaname = 'public'
AND NOT rowsecurity;Пустой результат значит, что RLS включен везде. Если список не пуст, для каждой строки нужно решить: либо это таблица со справочными данными без пользовательской привязки и её действительно можно оставить открытой на чтение, либо в ней хранятся чужие строки, и защиту нужно включать немедленно.
Включение делается одной командой на таблицу:
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;Но включенный RLS без единой политики закрывает доступ для всех, включая владельца данных. Это правильное поведение по умолчанию, а не баг: лучше временно сломанный интерфейс, чем открытая база. Дальше нужно написать сами политики.
Классический паттерн владения строкой выглядит так:
CREATE POLICY "Users can view own rows"
ON tasks FOR SELECT
USING (auth.uid() = user_id);Здесь важно использовать (select auth.uid()) в скобках, а не голый вызов функции. Это не только вопрос стиля: обернутый в подзапрос вызов Postgres кеширует один раз на запрос, а не выполняет заново для каждой строки, что на больших таблицах ощутимо ускоряет выборку.

RLS стоит включать сразу при создании таблицы, а не после запуска. Политику лучше писать под конкретную операцию: отдельно для SELECT, отдельно для INSERT, UPDATE и DELETE, а не одну общую на все действия.
Разработчики в разборах Supabase 101 советуют разделять операции: политика на чтение своих задач, отдельная политика на создание, третья на обновление только владельцем. Так проще понять логику каждого правила и найти ошибку, если что-то не работает. Общая политика «на все» скрывает баги: например, разрешает удаление там, где должно быть только чтение.
Для тестирования подходит простой прием: создать двух пользователей, зайти под каждым в отдельном браузере и попробовать открыть чужие данные напрямую. Если получилось, политика написана неверно. Этот же прием стоит гонять при каждом изменении схемы, а не один раз в начале проекта.
При работе с AI-ассистентом вроде Cursor полезно подключить ему доступ к документации Supabase перед тем, как просить сгенерировать политику. Модель тогда реже путает синтаксис старых версий RLS с текущим. И все равно результат нужно прогонять через проверочный SQL-запрос выше, а не доверять на слово.

Готовый промпт находит таблицы без RLS, политики вида USING (true) и несовпадение типов между owner_id и auth.uid(). Вставляется в Cursor, Claude Code или чат с моделью вместе со схемой базы.
Промпт работает с любой моделью, которой можно показать SQL-схему или дать доступ к MCP-серверу Supabase. Копируйте целиком:
Ты аудитор безопасности Supabase. Перед тобой SQL-схема моей базы данных (или дай себе доступ через MCP-сервер Supabase).
Проверь по каждой таблице:
1. Включен ли ROW LEVEL SECURITY (rowsecurity = true).
2. Есть ли хотя бы одна политика на SELECT, INSERT, UPDATE, DELETE отдельно.
3. Не содержит ли условие политики USING (true) или WITH CHECK (true) без дополнительных условий.
4. Совпадают ли типы данных в сравнениях с auth.uid() (должен быть uuid, а не bigint или text).
5. Использует ли политика (select auth.uid()) в подзапросе, а не голый вызов функции.
6. Не хранится ли service_role ключ в клиентском коде фронтенда.
Для каждой найденной проблемы дай: название таблицы, тип проблемы, готовый SQL для исправления, приоритет (критично/средне/можно отложить).
Такой аудит стоит гонять после каждой значимой миграции, а не только перед релизом. Особенно если схему правил AI-ассистент без ревью человеком.
Оба инструмента строят приложения поверх Supabase и наследуют одну и ту же слабость: RLS выключен по умолчанию. Разница в том, что Lovable чаще создает таблицы автоматически без участия разработчика, а в Cursor схему обычно пишет человек через AI-подсказку.
В Lovable пользователь часто вообще не видит SQL-миграцию, она генерируется и применяется в один клик при подключении Supabase. Это удобно для новичков, но снижает шанс, что кто-то заметит отсутствие политики. В Cursor разработчик обычно сам просматривает сгенерированный код перед коммитом, поэтому ошибка чаще ловится на этапе ревью, если у человека уже есть базовое понимание RLS.
Но вывод один и тот же для обоих инструментов: если стек это связка AI-билдер плюс Supabase, считайте RLS неправильно настроенным, пока не проверили сами. Разница в инструменте не меняет того факта, что ответственность за политики лежит на разработчике, а не на генераторе кода.

Row Level Security решает конкретную задачу лучше многих альтернатив, но у подхода есть и реальные ограничения, которые стоит знать заранее.
Сильные стороны:
Слабые стороны:

Что будет, если включить RLS, но не написать ни одной политики? Доступ к таблице будет полностью закрыт для всех, кроме запросов с service_role ключом. Это безопасное поведение по умолчанию, но приложение перестанет получать данные, пока политики не появятся.
Нужен ли RLS, если вся логика доступа уже проверяется на фронтенде? Да, обязательно. Проверка на фронтенде легко обходится прямым запросом к REST API Supabase с помощью anon key, который в любом случае виден в коде страницы.
Можно ли обойтись без RLS и держать всю логику в серверных функциях? Технически можно, если полностью закрыть прямой доступ клиента к базе и пропускать все запросы через Edge Functions с service_role ключом. Но это фактически отменяет главное преимущество Supabase, поэтому RLS почти всегда проще.
Как быстро проверить чужой или свой проект на Lovable на эту уязвимость? Выполните SQL-запрос из раздела про проверку RLS в SQL Editor Supabase, либо используйте готовый промпт для аудита выше вместе с Cursor или Claude Code.
Влияет ли RLS на скорость запросов? Влияет, но некритично при правильном написании. Ключевая оптимизация: использовать (select auth.uid()) вместо прямого вызова функции в условии политики, это позволяет Postgres кешировать значение на весь запрос.
Lovable исправил проблему из CVE-2025-48757? Платформа добавила встроенный security-сканер в версии 2.0 в апреле 2025 года. Он проверяет наличие политики, но не оценивает, насколько она реально ограничивает доступ, поэтому таблица с политикой USING (true) все еще проходит проверку.
Что делать, если проект уже в продакшене и RLS выключен? Сначала выполните аудит по SQL-запросу, затем включайте RLS на каждой таблице по очереди с политикой заглушкой на deny all, тестируйте на staging и только потом пишите реальные политики. Резкое включение на проде без подготовки временно сломает функциональность для всех пользователей.
Разобраться в архитектуре и стеке инструментов проще на реальных примерах. В каталоге VibeCoderz есть подробные обзоры Lovable и Cursor с их сильными и слабыми сторонами, а также полный каталог AI-инструментов для вайбкодинга. Если нужен взгляд со стороны на архитектуру или запуск проекта на Supabase, можно обсудить это на консультации с Максимом. Для тех, кто занимается настройкой инфраструктуры и безопасности регулярно, в каталоге агентов VibeCoderz есть отдельная ниша под DevOps-задачи.
Обновлено: июль 2026.