// docs / baas security / supabase rls scanner
Supabase RLS-szkenner: hiányzó vagy hibás row-level security-vel rendelkező táblák felderítése
A row-level security (RLS) az egyetlen, ami az ügyfeleid adatai és az internet között áll, amikor Supabase-alapú alkalmazást élesítesz. Az MI-kódoló eszközök RLS-formájú kódot generálnak, ami fordul, kikerül és csendben szivárogtatja az adatokat — táblák RLS engedélyezése nélkül, policy-k, amik olvasnak, de soha nem korlátoznak, predikátumok, amik egy oszlopot önmagával hasonlítanak össze. Ez a cikk megmutatja, mit tud egy Supabase RLS-szkenner kívülről bizonyítani, a vibe-kódolt alkalmazásokban felbukkanó négy tönkrement-RLS-formát, és hogyan szkenneld saját deploymentedet egy percnél is rövidebb idő alatt.
Mit tud bizonyítani egy külső RLS-szkennelés
Egy passzív RLS-szkennelés a Supabase által a https://[project].supabase.co/rest/v1/ címen kitett PostgREST-végpont ellen fut. Csak a közzétehető anon kulcsot használja — ugyanazt, amit a böngésződ —, és tábla-listázás metaadatokra, anonim olvasásokra és anonim írásokra szondázik. Soha nem hitelesít magát felhasználóként, és soha nem nyúl service-role-jogosultságokhoz. Bármit tud csinálni, azt egy nem hitelesített támadó is meg tudja csinálni az interneten.
Az adatbázison kívülről egy szkenner nagy bizonyossággal a következőket erősítheti meg:
- Az RLS le van tiltva egy táblán. A PostgREST sorokat ad vissza egy anonim
SELECT-re, ha az RLS ki van kapcsolva, vagy ha egy policy engedélyezi. Mindkettő találat. - Az anonim szerep tud táblákat listázni. Egy
GET /rest/v1/az anon kulccsal visszaadja az OpenAPI-sémát minden táblára, amelyre azanonszerepkörnek bármilyen jogosultsága van. Az MI-generált alkalmazások gyakran adnakUSAGE-t a sémára ésSELECT-et minden táblára, ami felfedi a teljes sématérképet még akkor is, ha az RLS megtagadja a tényleges olvasásokat. - Az anonim szerep tud INSERT-elni. Egy szondázó
POST, ami az oszlopforma kitalálását célozza, sikerül, ha az RLS-nek nincsINSERT-et tiltó policy-je — még akkor is, ha aSELECTle van zárva. - A service-role-kulcs a böngészőbundle-ben van. Az RLS-szel szomszédos: ha egy szkenner
SUPABASE_SERVICE_ROLE_KEY-t vagy bármilyenrole: service_roletartalmú JWT-t talál a JavaScript-bundle-ben, az RLS lényegtelen — aki ezt a kulcsot birtokolja, megkerül minden policy-t.
Mit nem tud bizonyítani egy külső szkennelés
Légy őszinte a szkenner határaival kapcsolatban. Egy külső RLS-szkennelés nem tudja olvasni a pg_policies tábládat, a migrációs fájljaidat vagy bármely policy pontos predikátumát. Black-box viselkedésből következtet, ami azt jelenti, hogy néha olyan találatot jelent, ami szándékos nyilvános adatnak bizonyul (egy marketinghírlevél-tábla, egy nyilvános termékkatalógus). A FixVibe-jelentés ezeket közepes magabiztosságúként jelöli, amikor a szkenner nem tudja egyértelműsíteni a szándékot — nézd meg a táblanevet és dönts.
Az MI-eszközök által termelt négy tönkrement RLS-forma
Amikor Cursort, Claude Code-ot, Lovable-t vagy Boltot irányítasz a Supabase-re, ugyanaz a négy tönkrement RLS-minta jelenik meg több ezer alkalmazáson keresztül. Mindegyik átmegy a típusellenőrzésen, fordul és élesítésre kerül:
Forma 1: Az RLS soha nem lett engedélyezve
A leggyakoribb hibamód. A migráció létrehozza a táblát, de a fejlesztő (vagy az MI-eszköz) elfelejti az ALTER TABLE ... ENABLE ROW LEVEL SECURITY-t. A PostgREST boldogan kiszolgálja az egész táblát bárkinek, akinél az anon kulcs van. Fix: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. A FORCE nem opcionális — nélküle a tábla tulajdonosa (és bármely tulajdonos-jogokkal rendelkező szerep) megkerüli az RLS-t.
ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;Forma 2: RLS engedélyezve, policy-k nélkül
Egy finomabb hiba. Az RLS engedélyezett, de nincsenek policy-k megírva. A PostgreSQL-ben az alapértelmezett a megtagadás, így a hitelesített felhasználók semmit sem látnak — és a fejlesztő hozzáad egy USING (true)-t, hogy az alkalmazás működjön, ami mindenkinek megengedi, hogy mindent olvasson. Fix: írj egy policy-t, ami auth.uid()-vel szűkít: CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); és egy megfelelő INSERT/UPDATE/DELETE policy-t.
CREATE POLICY "select_own"
ON public.[name]
FOR SELECT
USING (auth.uid() = user_id);Forma 3: A policy egy oszlopot önmagával hasonlít össze
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.
Forma 4: Policy a SELECT-en, de nem az INSERT/UPDATE-en
A fejlesztő lezárja az olvasásokat, de elfelejti az írásokat. Az RLS-policy-k parancsonként vannak. A FOR SELECT csak az olvasásokat védi; egy anonim kliens még mindig tud INSERT-elni, ha nincs olyan policy, ami megtagadja. Fix: írj parancsonként policy-t, vagy használj FOR ALL-t explicit USING és WITH CHECK záradékokkal.
Hogyan működik a FixVibe Supabase RLS-szkennere
A baas.supabase-rls ellenőrzés három fázisban fut, mindegyik explicit megbízhatósági szintekkel:
- 1. fázis — fingerprinting. A szkenner bejárja a deployolt alkalmazást, elemzi a JavaScript-bundle-jét, és kinyeri a Supabase projekt-URL-t és az anon kulcsot a futási konfigurációból. Nincs DNS-találgatás, nincs brute force — azt olvassa, amit a böngésző.
- 2. fázis — séma-felderítés. Egyetlen
GET /rest/v1/az anon kulccsal visszaadja az OpenAPI-sémát minden táblára, amelyet az anon szerep láthat. A szkenner rögzíti a táblaneveket, de ebben a fázisban nem olvas sorértékeket. - 3. fázis — olvasási és írási szondák. Minden felfedezett táblára a szkenner egy anonim
SELECT-et küldlimit=1-gyel. Ha sorok jönnek vissza, az RLS megengedő. A szkenner itt megáll — nem sorol fel sorokat, nem lapoz, nem módosít adatot. Az INSERT-szondák ellenőrzött domain-tulajdonjog és explicit opt-in mögé vannak korlátozva; soha nem futnak nem ellenőrzött célpontok ellen.
Minden találat tartalmazza a pontos kérés URL-jét, a válasz státuszát, a válasz formáját (csak fejléc) és a táblanevet. A találat alján lévő MI-fix prompt egy copy-paste SQL-blokk, amit a Supabase SQL-szerkesztőben futtatsz.
Mit tegyél, ha a szkenner talál valamit
Minden RLS-találat futási idejű vészhelyzet. A nyilvános PostgREST-végpontokat percek alatt szkennelik a támadók. A javítási sorrend mechanikus:
- Auditáld minden táblát. Futtasd a
SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public';-t a Supabase SQL-szerkesztőben. Mindenrowsecurity = falsesor probléma. - Engedélyezd az RLS-t minden nyilvános táblán. Alapértelmezésként
ENABLE ROW LEVEL SECURITYésFORCE ROW LEVEL SECURITYminden létrehozott táblán — tedd migrációs sablonná. - Írj policy-ket parancsonként. Ne használj
FOR ALL USING (true)-t. Írj explicit policy-ket SELECT-re, INSERT-re, UPDATE-re, DELETE-re — mindegyiketauth.uid()-re vagy azauth.jwt()-ből származó org-id oszlopra szűkítve. - Ellenőrizz egy másik fiókkal. Regisztrálj másik felhasználóként, próbáld meg egy másik felhasználó rekordjait olvasni a REST API-n keresztül közvetlenül. Ha a válasz
200, a policy hibás. - Szkennelj újra. A fix alkalmazása után futtass újra egy FixVibe-szkennelést ugyanarra az URL-re. A
baas.supabase-rlstalálatnak el kell tűnnie.
-- 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;Hogyan hasonlítható ez más szkennerekhez
A legtöbb általános DAST-eszköz (Burp Suite, OWASP ZAP, Nessus) nem tudja, mi az a PostgREST. Bejárják az alkalmazásodat, figyelmen kívül hagyják a /rest/v1/ útvonalat, és csak a HTML-oldalakról jelentenek, amelyeket megértenek. A Snyk és a Semgrep statikus elemző eszközök — megtalálják a hiányzó RLS-hívásokat tartalmazó migrációs fájlokat a repódban, de nem tudják bizonyítani, hogy a deployolt adatbázis hibásan van konfigurálva. A FixVibe ebbe a résbe ül: passzív, BaaS-tudatos, arra fókuszálva, mit tud egy nem hitelesített támadó bizonyítani a nyilvános URL-ből.
Gyakori kérdések
Olvassa vagy módosítja a szkenner az adataimat?
Nem. A passzív szkennelések legfeljebb egy SELECT ... limit=1-et küldenek minden felfedezett táblára, hogy megerősítsék, az RLS engedélyezi-e az anonim olvasásokat. A szkenner rögzíti a válasz formáját, nem a sortartalmat. Az INSERT-, UPDATE- és DELETE-szondák ellenőrzött domain-tulajdonjog mögé vannak korlátozva, és soha nem futnak nem ellenőrzött célpontok ellen.
Működik ez, ha a Supabase-projektem szüneteltetve van vagy egyedi doménen fut?
A szüneteltetett projektek 503-at adnak vissza minden kérésre — a szkenner elérhetetlenként jelenti a projektet. Az egyedi domének működnek, amíg a deployolt alkalmazás betölti a Supabase-kliens-SDK-t a böngészőben; a szkenner a projekt-URL-t mindenképp a bundle-ből nyeri ki.
Mi van, ha az anon kulcsom rotálva lesz vagy a publishable kulcsom változik?
Futtasd újra a szkennelést. A szkenner minden futáskor újra kinyeri a kulcsot az aktuális bundle-ből. A rotáció csak az előző jelentést érvényteleníti, nem az adatbázis policy-állapotát.
Ellenőrzi a szkenner az új Supabase publishable-kulcs modellt (<code>sb_publishable_*</code>)?
Igen. A detektor felismeri mind a régi anon JWT-ket, mind az újabb sb_publishable_* kulcsokat, és azonosan kezeli őket — mindkettő nyilvánosnak szánt, és mindkettő az RLS-t hagyja az egyetlen védelmi vonalként.
Következő lépések
Futtass egy ingyenes FixVibe-szkennelést az éles URL-edre — a baas.supabase-rls ellenőrzés minden csomagban engedélyezett, beleértve az ingyenest is. A Supabase-projektből kiszivároghatóak mélyebb áttekintéséhez olvasd el A Supabase service role kulcs JavaScriptben felfedve és A Supabase storage bucket biztonsági checklist cikkeket. Az összes BaaS-szolgáltatóra kiterjedő ernyőszemlélethez olvasd el a BaaS hibás konfiguráció szkenner cikket.
