// docs / baas security / supabase rls scanner
Supabase RLS skener: pronađite tabele s nedostajućom ili neispravnom row-level security
Row-level security (RLS) je jedino što stoji između podataka vaših korisnika i interneta kada isporučite aplikaciju koja koristi Supabase. AI alati za kodiranje generiraju RLS-oblikovani kod koji se kompajlira, isporučuje i tiho curi podatke — tabele kreirane bez uključenog RLS-a, politike koje čitaju ali nikada ne ograničavaju, predikati koji upoređuju kolonu sa samom sobom. Ovaj članak pokazuje šta Supabase RLS skener može dokazati izvana, četiri oblika neispravnog RLS-a koji se pojavljuju u vibe-coded aplikacijama i kako skenirati vlastiti deployment u manje od minute.
Šta eksterni RLS sken može dokazati
Pasivni RLS sken pokreće se prema PostgREST endpointu koji Supabase izlaže na https://[project].supabase.co/rest/v1/. Koristi samo publishable anon ključ — isti ključ koji koristi vaš preglednik — i ispituje metapodatke liste tabela, anonimna čitanja i anonimna pisanja. Nikada se ne autentificira kao korisnik niti dodiruje privilegije service-rolea. Sve što on može učiniti, može i neautenticirani napadač s interneta.
Izvan baze podataka, skener može potvrditi sljedeće s visokom pouzdanošću:
- RLS je onemogućen na tabeli. PostgREST vraća redove na anonimni
SELECTkada je RLS isključen ili kada to politika dozvoljava. Oba slučaja su nalaz. - Anonimna uloga može listati tabele.
GET /rest/v1/s anon ključem vraća OpenAPI shemu za svaku tabelu na kojoj ulogaanonima bilo kakvu privilegiju. AI-generirane aplikacije često dodjeljujuUSAGEna shemu iSELECTna svaku tabelu, što izlaže potpunu shemu čak i kada RLS onemogućava stvarna čitanja. - Anonimna uloga može vršiti insert. Probni
POSTs pogađanjem oblika kolona uspjet će ako RLS nemaINSERTpolitiku koja to zabranjuje — čak i ako jeSELECTzaključan. - Service-role ključ nalazi se u browser bundleu. Susjedno RLS-u: ako skener pronađe
SUPABASE_SERVICE_ROLE_KEYili bilo koji JWT srole: service_roleu JavaScript bundleu, RLS je suvišan — onaj ko drži taj ključ zaobilazi svaku politiku.
Šta eksterni sken ne može dokazati
Budite iskreni o granicama skenera. Eksterni RLS sken ne može čitati vašu tabelu pg_policies, vaše migracione fajlove ni tačan predikat bilo koje politike. Zaključuje na osnovu black-box ponašanja, što znači da će ponekad prijaviti nalaz koji se ispostavi kao namjerno javan podatak (tabela marketing newslettera, javni katalog proizvoda). FixVibe izvještaj označava ove kao srednje pouzdanost kada skener ne može razlučiti namjeru — pregledajte ime tabele i odlučite.
Četiri oblika neispravnog RLS-a koje AI alati proizvode
Kada uperite Cursor, Claude Code, Lovable ili Bolt prema Supabaseu, ista četiri obrasca neispravnog RLS-a pojavljuju se u hiljadama aplikacija. Svaki prolazi type-check, kompajlira se i isporučuje:
Oblik 1: RLS nikada nije uključen
Najčešći način neuspjeha. Migracija kreira tabelu, ali developer (ili AI alat) zaboravi ALTER TABLE ... ENABLE ROW LEVEL SECURITY. PostgREST veselo poslužuje cijelu tabelu svakome ko ima anon ključ. Popravak: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. FORCE nije opcionalan — bez njega vlasnik tabele (i svaka uloga s vlasništvom nad tabelom) zaobilazi RLS.
ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;Oblik 2: RLS uključen, bez politika
Suptilniji neuspjeh. RLS je uključen, ali nije napisana nijedna politika. Default u PostgreSQL-u je deny, pa autenticirani korisnici ne vide ništa — i developer dodaje USING (true) da bi aplikacija radila, što dozvoljava svima da čitaju sve. Popravak: napišite politiku koja se ograničava preko auth.uid(): CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); i odgovarajuću politiku za INSERT/UPDATE/DELETE.
CREATE POLICY "select_own"
ON public.[name]
FOR SELECT
USING (auth.uid() = user_id);Oblik 3: Politika upoređuje kolonu sa samom sobom
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.
Oblik 4: Politika na SELECT-u ali ne i na INSERT-u/UPDATE-u
Developer zaključava čitanja, ali zaboravlja pisanja. RLS politike su per-komanda. FOR SELECT štiti samo čitanja; anonimni klijent i dalje može izvršiti INSERT ako to nijedna politika ne zabranjuje. Popravak: napišite politiku po komandi ili koristite FOR ALL s eksplicitnim USING i WITH CHECK klauzulama.
Kako radi FixVibe Supabase RLS skener
Provjera baas.supabase-rls radi u tri faze, svaka s eksplicitnim nivoima pouzdanosti:
- Faza 1 — fingerprintiranje. Skener crawla deploy-anu aplikaciju, parsira njen JavaScript bundle i ekstrahira Supabase project URL i anon ključ iz runtime konfiguracije. Bez pogađanja DNS-a, bez brute-forcea — čita ono što čita preglednik.
- Faza 2 — otkrivanje sheme. Jedan
GET /rest/v1/s anon ključem vraća OpenAPI shemu za svaku tabelu koju anonimna uloga može vidjeti. Skener bilježi imena tabela, ali u ovoj fazi ne čita podatke redova. - Faza 3 — probe čitanja i pisanja. Za svaku otkrivenu tabelu, skener izdaje jedan anonimni
SELECTslimit=1. Ako se vrate redovi, RLS je permisivan. Skener tu staje — ne nabraja redove, ne paginira, ne mijenja podatke. INSERT probe su uvjetovane verificiranim vlasništvom domene i eksplicitnim opt-inom; nikada se ne pokreću prema neverificiranim ciljevima.
Svaki nalaz dolazi s tačnim URL-om zahtjeva, statusom odgovora, oblikom odgovora (samo headeri) i imenom tabele. AI prompt za popravak na dnu nalaza je copy-paste SQL blok koji pokrećete u Supabase SQL editoru.
Šta učiniti kada skener nešto pronađe
Svaki RLS nalaz je runtime hitnost. Javne PostgREST endpointove napadači skeniraju u roku od nekoliko minuta. Sekvenca remedijacije je mehanička:
- Auditujte svaku tabelu. Pokrenite
SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public';u Supabase SQL editoru. Svaki red srowsecurity = falseje problem. - Uključite RLS na svakoj javnoj tabeli. Default na
ENABLE ROW LEVEL SECURITYiFORCE ROW LEVEL SECURITYna svakoj kreiranoj tabeli — neka to bude template za migracije. - Pišite politike komanda-po-komanda. Ne koristite
FOR ALL USING (true). Napišite eksplicitne politike za SELECT, INSERT, UPDATE, DELETE — svaku ograničenu prekoauth.uid()ili kolone org-id izauth.jwt(). - Verifikujte drugim računom. Registrujte se kao drugi korisnik, pokušajte čitati zapise drugog korisnika direktno preko REST API-ja. Ako je odgovor
200, politika je neispravna. - Ponovo skenirajte. Nakon primjene popravka, ponovo pokrenite FixVibe sken prema istom URL-u. Nalaz
baas.supabase-rlstrebao bi nestati.
-- 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;Kako se ovo poredi s drugim skenerima
Većina generičkih DAST alata (Burp Suite, OWASP ZAP, Nessus) ne zna šta je PostgREST. Crawlat će vašu aplikaciju, ignorirati putanju /rest/v1/ i prijaviti HTML stranice koje razumiju. Snyk i Semgrep su alati za statičku analizu — pronalaze migracione fajlove u vašem repozitoriju s nedostajućim RLS pozivima, ali ne mogu dokazati da je deploy-ana baza pogrešno konfigurisana. FixVibe popunjava taj prostor: pasivno, sa znanjem o BaaS-u, fokusirano na ono što neautenticirani napadač može dokazati s javnog URL-a.
Često postavljana pitanja
Hoće li skener čitati ili mijenjati moje podatke?
Ne. Pasivni skenovi izdaju najviše jedan SELECT ... limit=1 po otkrivenoj tabeli da bi potvrdili dozvoljava li RLS anonimna čitanja. Skener bilježi oblik odgovora, a ne sadržaj redova. INSERT, UPDATE i DELETE probe su uvjetovane verificiranim vlasništvom domene i nikada se ne pokreću prema neverificiranim ciljevima.
Radi li ovo ako je moj Supabase projekat pauziran ili na prilagođenoj domeni?
Pauzirani projekti vraćaju 503 na svaki zahtjev — skener prijavljuje projekat kao nedostupan. Prilagođene domene rade dokle god deploy-ana aplikacija i dalje učitava Supabase klijentski SDK u pregledniku; skener u svakom slučaju izvlači project URL iz bundlea.
Šta ako se moj anon ključ rotira ili promijeni publishable ključ?
Ponovo pokrenite sken. Skener ponovo izvlači ključ iz trenutnog bundlea pri svakom pokretanju. Rotacija poništava samo prethodni izvještaj, ne i stanje politika u bazi.
Provjerava li skener novi Supabase model publishable-key (<code>sb_publishable_*</code>)?
Da. Detektor prepoznaje i naslijeđene anon JWT-ove i novije sb_publishable_* ključeve i tretira ih identično — oba su namijenjena da budu javna i oba ostavljaju RLS kao jedinu liniju odbrane.
Sljedeći koraci
Pokrenite besplatan FixVibe sken prema svom produkcijskom URL-u — provjera baas.supabase-rls je uključena u svakom paketu, uključujući i besplatni. Za dublji uvid u to šta još može curiti iz Supabase projekta, pogledajte Supabase service role ključ izložen u JavaScriptu i Sigurnosna checklista za Supabase storage. Za pregled iz ptičje perspektive za sve BaaS providere, pročitajte Skener BaaS pogrešnih konfiguracija.
