FixVibe

// docs / baas security / supabase rls scanner

Сканер за Supabase RLS: намерете таблици с липсваща или счупена сигурност на ниво ред

Сигурността на ниво ред (RLS) е единственото нещо, което стои между данните на клиентите ви и интернет, когато пуснете приложение, базирано на Supabase. AI инструментите за кодиране генерират код във формата на RLS, който се компилира, изпраща и тихомълком изтича данни — таблици, създадени без включен RLS, политики, които четат, но никога не ограничават, предикати, които сравняват колона със себе си. Тази статия показва какво може да докаже един Supabase RLS скенер отвън, четирите форми на счупен RLS, които се появяват във vibe-кодирани приложения, и как да сканирате собствения си deploy за по-малко от минута.

Какво може да докаже едно външно RLS сканиране

Пасивно RLS сканиране се изпълнява срещу крайната точка PostgREST, която Supabase излага на https://[project].supabase.co/rest/v1/. Използва само публикуемия anon ключ — същия ключ, който използва браузърът ви — и сондира за метаданни за списъци на таблици, анонимни четения и анонимни записи. Никога не се автентикира като потребител и никога не докосва привилегиите на сервизната роля. Всичко, което може да направи, може да го направи и неавтентикиран нападател в интернет.

Извън базата данни скенерът може да потвърди следното с висока увереност:

  • RLS е изключен на таблица. PostgREST връща редове за анонимен SELECT, когато RLS е изключен или когато политика го позволява. И двата случая са откритие.
  • Анонимната роля може да изброява таблици. GET /rest/v1/ с anon ключ връща OpenAPI схемата за всяка таблица, върху която ролята anon има някакви привилегии. Приложенията, генерирани от AI, често дават USAGE върху схемата и SELECT върху всяка таблица, което излага пълната карта на схемата дори когато RLS отказва действителните четения.
  • Анонимната роля може да вмъква. Сондиращ POST с предположение за формата на колоните ще успее, ако RLS няма INSERT политика, която да го отказва — дори ако SELECT е заключен.
  • Сервизният ключ е в браузърния bundle. Съседно на RLS: ако скенер намери SUPABASE_SERVICE_ROLE_KEY или какъвто и да е JWT с role: service_role в JavaScript bundle-а, RLS става без значение — притежателят на този ключ заобикаля всяка политика.

Какво не може да докаже едно външно сканиране

Бъдете честни относно границите на скенера. Едно външно RLS сканиране не може да чете вашата pg_policies таблица, миграционните ви файлове или точния предикат на която и да е политика. То извежда заключения от black-box поведение, което означава, че понякога ще докладва откритие, което се оказва умишлено публични данни (таблица за маркетинг бюлетин, публичен продуктов каталог). Отчетът на FixVibe маркира тези като средна увереност, когато скенерът не може да разграничи намерението — прегледайте името на таблицата и решете.

Четирите форми на счупен RLS, които AI инструментите произвеждат

Когато насочите Cursor, Claude Code, Lovable или Bolt към Supabase, същите четири модела на счупен RLS възникват в хиляди приложения. Всеки от тях преминава type-check, компилира се и се пуска в продукция:

Форма 1: RLS никога не е активиран

Най-разпространеният режим на отказ. Миграцията създава таблицата, но разработчикът (или AI инструментът) забравя ALTER TABLE ... ENABLE ROW LEVEL SECURITY. PostgREST с радост обслужва цялата таблица на всеки с anon ключа. Поправка: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. FORCE не е по избор — без него собственикът на таблицата (и всяка роля със собственост на таблицата) заобикаля RLS.

sql
ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.[name] FORCE  ROW LEVEL SECURITY;

Форма 2: RLS активиран, без политики

По-фин отказ. RLS е активиран, но не са написани политики. По подразбиране в PostgreSQL е отказ, така че автентикираните потребители не виждат нищо — и разработчикът добавя USING (true), за да накара приложението да работи, което позволява на всеки да чете всичко. Поправка: напишете политика, която ограничава по auth.uid(): CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); и съответстваща INSERT/UPDATE/DELETE политика.

sql
CREATE POLICY "select_own"
  ON public.[name]
  FOR SELECT
  USING (auth.uid() = user_id);

Форма 3: Политиката сравнява колона със себе си

A copy-paste artefact. The developer writes <code>USING (user_id = user_id)</code> — which is always true — instead of <code>USING (auth.uid() = user_id)</code>. Type-checks pass; the policy permits every row. <strong>Fix:</strong> always compare a column to a function call (<code>auth.uid()</code>, <code>auth.jwt()->>'org_id'</code>, etc.), never to itself or to a constant.

Форма 4: Политика на SELECT, но не на INSERT/UPDATE

Разработчикът заключва четенията, но забравя записите. RLS политиките са за всяка команда. FOR SELECT защитава само четения; анонимен клиент все още може да INSERT, ако няма политика, която да го отказва. Поправка: напишете политика за всяка команда или използвайте FOR ALL с явни USING и WITH CHECK клаузи.

Как работи Supabase RLS скенерът на FixVibe

Проверката baas.supabase-rls работи на три етапа, всеки с явни нива на увереност:

  1. Етап 1 — отпечатък. Скенерът обхожда внедреното приложение, анализира неговия JavaScript bundle и извлича URL адреса на проекта Supabase и anon ключа от runtime конфигурацията. Без отгатване на DNS, без brute force — той чете това, което чете браузърът.
  2. Етап 2 — откриване на схема. Едно GET /rest/v1/ с anon ключа връща OpenAPI схемата за всяка таблица, която anon ролята може да види. Скенерът записва имената на таблиците, но не чете данни на редове на този етап.
  3. Етап 3 — сондажи за четене и запис. За всяка открита таблица скенерът издава един анонимен SELECT с limit=1. Ако се връщат редове, RLS е разрешителен. Скенерът спира там — не изброява редове, не пагинира, не модифицира данни. INSERT сондажите са ограничени до проверена собственост на домейна и явно opt-in; те никога не се изпълняват срещу непроверени цели.

Всяко откритие идва с точния URL на заявката, статуса на отговора, формата на отговора (само заглавки) и името на таблицата. AI промптът за поправка в долната част на откритието е copy-paste SQL блок, който изпълнявате в SQL редактора на Supabase.

Какво да направите, когато скенерът открие нещо

Всяко RLS откритие е спешен случай по време на изпълнение. Публичните PostgREST крайни точки се сканират от нападатели за минути. Последователността за отстраняване е механична:

  1. Одитирайте всяка таблица. Изпълнете SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'; в SQL редактора на Supabase. Всеки ред с rowsecurity = false е проблем.
  2. Активирайте RLS на всяка публична таблица. По подразбиране ENABLE ROW LEVEL SECURITY и FORCE ROW LEVEL SECURITY на всяка създадена таблица — направете го шаблон за миграция.
  3. Пишете политики команда по команда. Не използвайте FOR ALL USING (true). Напишете явни политики за SELECT, INSERT, UPDATE, DELETE — всяка ограничена до auth.uid() или org-id колона от auth.jwt().
  4. Проверете със втори акаунт. Регистрирайте се като различен потребител, опитайте се да прочетете записите на друг потребител директно чрез REST API. Ако отговорът е 200, политиката е счупена.
  5. Сканирайте отново. След прилагане на поправката, изпълнете отново FixVibe сканиране срещу същия URL. Откритието baas.supabase-rls трябва да изчезне.
sql
-- Audit every table for missing RLS. Run in the Supabase SQL editor.
SELECT schemaname, tablename, rowsecurity
FROM   pg_tables
WHERE  schemaname = 'public'
ORDER  BY rowsecurity, tablename;

Как това се сравнява с други скенери

Повечето общи DAST инструменти (Burp Suite, OWASP ZAP, Nessus) не знаят какво е PostgREST. Те ще обходят приложението ви, ще игнорират пътя /rest/v1/ и ще докладват за HTML страниците, които разбират. Snyk и Semgrep са инструменти за статичен анализ — те намират миграционни файлове в repo-то ви с липсващи RLS извиквания, но не могат да докажат, че внедрената база данни е неправилно конфигурирана. FixVibe попада в пропуска: пасивен, BaaS-осведомен, фокусиран върху това, което неавтентикиран нападател може да докаже от публичния URL.

Често задавани въпроси

Ще чете ли или модифицира скенерът данните ми?

Не. Пасивните сканирания изпълняват най-много един SELECT ... limit=1 за открита таблица, за да потвърдят дали RLS позволява анонимни четения. Скенерът записва формата на отговора, а не съдържанието на редовете. INSERT, UPDATE и DELETE сондажите са ограничени до проверена собственост на домейна и никога не се изпълняват срещу непроверени цели.

Работи ли това, ако моят Supabase проект е спрян или на персонализиран домейн?

Спрените проекти връщат 503 на всяка заявка — скенерът докладва проекта като недостъпен. Персонализираните домейни работят, стига внедреното приложение все още да зарежда Supabase клиентския SDK в браузъра; скенерът извлича URL адреса на проекта от bundle-а така или иначе.

Какво ако моят anon ключ е ротиран или публикуемият ми ключ се промени?

Изпълнете сканирането отново. Скенерът извлича ключа от текущия bundle при всяко изпълнение. Ротацията анулира само предишния отчет, не и състоянието на политиките в базата данни.

Проверява ли скенерът новия модел с публикуем ключ на Supabase (<code>sb_publishable_*</code>)?

Да. Детекторът разпознава както наследени anon JWT, така и по-новите sb_publishable_* ключове и ги третира еднакво — и двата са предназначени да бъдат публични и оставят RLS като единствена линия на защита.

Следващи стъпки

Изпълнете безплатно FixVibe сканиране срещу production URL — проверката baas.supabase-rls е активирана във всеки план, включително безплатния. За по-задълбочен прочит на това, какво още може да изтече от Supabase проект, вижте Сервизният ключ на Supabase, разкрит в JavaScript и Контролен списък за сигурност на storage bucket на Supabase. За общ преглед на всички BaaS доставчици, прочетете Скенер за неправилни конфигурации на BaaS.

// сканирайте вашата baas повърхност

Намерете отворената таблица, преди някой друг да го направи.

Въведете production URL. FixVibe изброява доставчиците на BaaS, с които комуникира приложението ви, снема отпечатъци от публичните им крайни точки и докладва какво може да прочете или запише неавтентикиран клиент. Безплатно, без инсталация, без карта.

  • Безплатен план — 3 сканирания / месец, без карта при регистрация.
  • Пасивен отпечатък на BaaS — не се изисква проверка на домейн.
  • Supabase, Firebase, Clerk, Auth0, Appwrite и още.
  • AI промптове за поправка на всяко откритие — поставете обратно в Cursor / Claude Code.
Стартирайте безплатно BaaS сканиране

не се изисква регистрация

Сканер за Supabase RLS: намерете таблици с липсваща или счупена сигурност на ниво ред — Docs · FixVibe