// docs / baas security / supabase rls scanner
Supabase RLS -skanneri: löydä taulut, joista puuttuu tai jotka on rikkonut row-level securityn
Row-level security (RLS) on ainoa asia, joka erottaa asiakkaidesi datan internetistä, kun julkaiset Supabase-pohjaisen sovelluksen. AI-koodaustyökalut tuottavat RLS-muotoista koodia, joka kääntyy, julkaistaan ja vuotaa dataa hiljaisesti — tauluja luodaan ilman RLS:n aktivointia, policyjä, jotka lukevat mutta eivät koskaan rajoita, predikaatteja, jotka vertaavat saraketta itseensä. Tässä artikkelissa näytetään, mitä Supabase RLS -skanneri voi todistaa ulkopuolelta, ne neljä rikkinäisen RLS:n muotoa, jotka ilmenevät vibe-koodatuissa sovelluksissa, ja miten skannaat oman julkaisusi alle minuutissa.
Mitä ulkoinen RLS-skannaus voi todistaa
Passiivinen RLS-skannaus ajetaan PostgREST-päätepistettä vastaan, jonka Supabase paljastaa osoitteessa https://[project].supabase.co/rest/v1/. Se käyttää vain julkaistavaa anon-avainta — samaa, jota selaimesi käyttää — ja tutkii taululista-metadataa, anonyymejä lukuja ja anonyymejä kirjoituksia. Se ei koskaan autentikoidu käyttäjäksi eikä koske service-role-oikeuksiin. Kaiken, mitä se voi tehdä, voi myös tuntematon hyökkääjä internetissä tehdä.
Tietokannan ulkopuolelta skanneri voi vahvistaa seuraavat suurella varmuudella:
- RLS on poistettu käytöstä taulussa. PostgREST palauttaa rivit anonyymille
SELECT-kyselylle, kun RLS on pois päältä tai kun policy sallii sen. Kumpikin tapaus on löydös. - Anonyymi rooli voi listata taulut.
GET /rest/v1/anon-avaimella palauttaa OpenAPI-skeeman jokaisesta taulusta, johon roolillaanonon jokin oikeus. AI-generoidut sovellukset myöntävät useinUSAGE-oikeuden skeemaan jaSELECT-oikeuden jokaiseen tauluun, mikä paljastaa koko skeemakartan, vaikka RLS estäisi varsinaiset luvut. - Anonyymi rooli voi suorittaa INSERT-operaation. Tutkiva
POSTarvauksella sarakemuodosta onnistuu, jos RLS:llä ei oleINSERT-policya, joka kieltäisi sen — vaikkaSELECTolisi lukittu. - Service-role-avain on selainpaketissa. RLS:n vierellä: jos skanneri löytää
SUPABASE_SERVICE_ROLE_KEY:n tai minkä tahansa JWT:n, jossa onrole: service_role, JavaScript-paketista, RLS on merkityksetön — avaimen haltija ohittaa kaikki policyt.
Mitä ulkoinen skannaus ei voi todistaa
Ole rehellinen skannerin rajoista. Ulkoinen RLS-skannaus ei voi lukea pg_policies-tauluasi, migraatiotiedostojasi tai minkään policyn tarkkaa predikaattia. Se päättelee black-box-käyttäytymisestä, mikä tarkoittaa, että se raportoi joskus löydöksen, joka osoittautuukin tarkoitukselliseksi julkiseksi dataksi (markkinoinnin uutiskirjetaulu, julkinen tuotekatalogi). FixVibe-raportti merkitsee nämä keskitason varmuudella, kun skanneri ei voi erottaa tarkoitusta — katso taulun nimi ja päätä.
Neljä AI-työkalujen tuottamaa rikkinäisen RLS:n muotoa
Kun osoitat Cursorin, Claude Coden, Lovablen tai Boltin Supabaseen, samat neljä rikkinäisen RLS:n kuviota toistuvat tuhansissa sovelluksissa. Jokainen läpäisee tyyppitarkistuksen, kääntyy ja julkaistaan:
Muoto 1: RLS ei koskaan käytössä
Yleisin epäonnistumistila. Migraatio luo taulun mutta kehittäjä (tai AI-työkalu) unohtaa ALTER TABLE ... ENABLE ROW LEVEL SECURITY:n. PostgREST tarjoilee mielellään koko taulun kenelle tahansa, jolla on anon-avain. Korjaus: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. FORCE ei ole valinnainen — ilman sitä taulun omistaja (ja jokainen rooli, jolla on taulun omistus) ohittaa RLS:n.
ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;Muoto 2: RLS käytössä, ei policyjä
Hienovaraisempi vika. RLS on käytössä mutta policyjä ei ole kirjoitettu. PostgreSQL:n oletus on kielto, joten autentikoituneet käyttäjät eivät näe mitään — ja kehittäjä lisää USING (true):n saadakseen sovelluksen toimimaan, mikä sallii kaikkien lukea kaikkea. Korjaus: kirjoita policy, joka rajaa auth.uid():lla: CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); ja vastaava INSERT/UPDATE/DELETE-policy.
CREATE POLICY "select_own"
ON public.[name]
FOR SELECT
USING (auth.uid() = user_id);Muoto 3: Policy vertaa saraketta itseensä
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.
Muoto 4: Policy SELECTille mutta ei INSERTille/UPDATElle
Kehittäjä lukitsee luvut mutta unohtaa kirjoitukset. RLS-policyt ovat komentokohtaisia. FOR SELECT suojaa vain luvut; anonyymi asiakas voi yhä INSERT-toiminnon suorittaa, jos mikään policy ei estä sitä. Korjaus: kirjoita policy komentoa kohden, tai käytä FOR ALL:ia eksplisiittisillä USING- ja WITH CHECK-lausekkeilla.
Miten FixVibe Supabase RLS -skanneri toimii
Tarkistus baas.supabase-rls ajetaan kolmessa vaiheessa, jokaisessa eksplisiittinen varmuustaso:
- Vaihe 1 — sormenjälkitunnistus. Skanneri ryömii julkaistun sovelluksen läpi, jäsentää sen JavaScript-paketin ja poimii Supabase-projektin URL:n ja anon-avaimen ajonaikaisesta konfiguraatiosta. Ei DNS-arvauksia, ei brute forcea — se lukee sen, minkä selaimesi lukee.
- Vaihe 2 — skeeman löytäminen. Yksi
GET /rest/v1/anon-avaimella palauttaa OpenAPI-skeeman jokaisesta taulusta, jonka anon-rooli näkee. Skanneri tallentaa taulun nimet mutta ei lue rividataa tässä vaiheessa. - Vaihe 3 — luku- ja kirjoitustutkimukset. Jokaiselle löydetylle taululle skanneri lähettää yhden anonyymin
SELECT-kyselyn, jossa onlimit=1. Jos rivejä palautuu, RLS on salliva. Skanneri pysähtyy siihen — se ei luetteloi rivejä, ei sivutuksia eikä muuta dataa. INSERT-tutkimukset on rajattu vahvistetun domain-omistajuuden ja eksplisiittisen suostumuksen taakse; niitä ei koskaan ajeta vahvistamattomia kohteita vastaan.
Jokainen löydös toimitetaan tarkalla pyyntö-URL:llä, vastauksen statuksella, vastauksen muodolla (vain header) ja taulun nimellä. AI-korjauskehote löydöksen alaosassa on copy-paste-SQL-lohko, joka ajetaan Supabase SQL -editorissa.
Mitä tehdä, kun skanneri löytää jotain
Jokainen RLS-löydös on ajonaikainen hätätilanne. Julkiset PostgREST-päätepisteet skannataan hyökkääjien toimesta minuuteissa. Korjaussekvenssi on mekaaninen:
- Tarkista jokainen taulu. Aja
SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public';Supabase SQL -editorissa. Jokainen rivi, jossarowsecurity = false, on ongelma. - Ota RLS käyttöön jokaisessa julkisessa taulussa. Aseta oletukseksi
ENABLE ROW LEVEL SECURITYjaFORCE ROW LEVEL SECURITYjokaiseen luotuun tauluun — tee siitä migraatiomalli. - Kirjoita policyt komento kerrallaan. Älä käytä
FOR ALL USING (true):ta. Kirjoita eksplisiittiset policyt SELECTille, INSERTille, UPDATElle, DELETElle — jokainen rajattunaauth.uid():hen tai org-id-sarakkeeseenauth.jwt():sta. - Verifioi toisella tilillä. Rekisteröidy toisena käyttäjänä, yritä lukea toisen käyttäjän tietueita suoraan REST-API:n kautta. Jos vastaus on
200, policy on rikki. - Skannaa uudelleen. Korjauksen jälkeen aja FixVibe-skannaus uudelleen samaa URL:ää vastaan.
baas.supabase-rls-löydöksen pitäisi kadota.
-- 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;Miten tämä vertautuu muihin skannereihin
Useimmat geneeriset DAST-työkalut (Burp Suite, OWASP ZAP, Nessus) eivät tiedä, mitä PostgREST on. Ne ryömivät sovelluksesi läpi, sivuuttavat /rest/v1/-polun ja raportoivat HTML-sivuista, joita ne ymmärtävät. Snyk ja Semgrep ovat staattisia analyysityökaluja — ne löytävät migraatiotiedostot repostasi, joista RLS-kutsut puuttuvat, mutta ne eivät voi todistaa, että julkaistu tietokanta on virhekonfiguroitu. FixVibe asettuu tähän aukkoon: passiivinen, BaaS-tietoinen, keskittynyt siihen, mitä tuntematon hyökkääjä voi todistaa julkisesta URL:stä.
Usein kysytyt kysymykset
Lukeeko tai muokkaako skanneri dataani?
Ei. Passiiviset skannaukset lähettävät korkeintaan yhden SELECT ... limit=1-kyselyn löydettyä taulua kohti vahvistaakseen, salliiko RLS anonyymit luvut. Skanneri tallentaa vastauksen muodon, ei rivien sisältöä. INSERT-, UPDATE- ja DELETE-tutkimukset on rajattu vahvistetun domain-omistajuuden taakse, eikä niitä koskaan ajeta vahvistamattomia kohteita vastaan.
Toimiiko tämä, jos Supabase-projektini on pysäytetty tai mukautetussa domainissa?
Pysäytetyt projektit palauttavat 503:n jokaisessa pyynnössä — skanneri raportoi projektin tavoittamattomana. Mukautetut domainit toimivat niin kauan kuin julkaistu sovellus yhä lataa Supabase-klientti-SDK:n selaimeen; skanneri poimii projektin URL:n paketista joka tapauksessa.
Entä jos anon-avaimeni rotatoidaan tai julkaistava avaimeni muuttuu?
Aja skannaus uudelleen. Skanneri poimii avaimen uudelleen nykyisestä paketista jokaisella ajokerralla. Rotaatio mitätöi vain edellisen raportin, ei tietokannan policy-tilaa.
Tarkistaako skanneri uuden Supabase julkaistava-avain-mallin (<code>sb_publishable_*</code>)?
Kyllä. Tunnistin tunnistaa sekä vanhat anon-JWT:t että uudemmat sb_publishable_*-avaimet ja käsittelee niitä identtisesti — molemmat on tarkoitettu julkisiksi ja molemmat jättävät RLS:n ainoaksi puolustuslinjaksi.
Seuraavat askeleet
Aja ilmainen FixVibe-skannaus tuotanto-URL:ääsi vastaan — baas.supabase-rls-tarkistus on käytössä jokaisessa suunnitelmassa, mukaan lukien ilmaistaso. Syvempää lukemista varten siitä, mitä muuta Supabase-projektista voi vuotaa, katso Supabase service-role-avain paljastunut JavaScriptissä ja Supabasen storage-bucketin tietoturvatarkistuslista. Kokonaisnäkymää varten kaikkien BaaS-tarjoajien yli lue BaaS-virhekonfiguraatioskanneri.
