// docs / baas security / supabase rls scanner
Supabase RLS scanner: ગુમ થયેલી અથવા તૂટેલી row-level security ધરાવતી tables શોધો
જ્યારે તમે Supabase-આધારિત app ship કરો છો, ત્યારે Row-level security (RLS) જ તમારા ગ્રાહકોના ડેટા અને ઇન્ટરનેટ વચ્ચે ઉભી રહેલી એકમાત્ર વસ્તુ છે. AI કોડિંગ ટૂલ એવો RLS-આકારનો કોડ બનાવે છે જે compile થાય, ship થાય, અને ચૂપચાપ ડેટા leak કરે — RLS enable કર્યા વગર બનેલી tables, એવી policies જે વાંચે પણ ક્યારેય પ્રતિબંધિત ન કરે, એવા predicates જે એક column ને પોતાની સાથે સરખાવે. આ લેખ બતાવે છે કે Supabase RLS scanner બહારથી શું સાબિત કરી શકે, vibe-coded apps માં દેખાતા તૂટેલા-RLS ના ચાર આકાર, અને એક મિનિટ કરતા ઓછા સમયમાં તમારા પોતાના deployment ને કેવી રીતે scan કરવું.
બાહ્ય RLS scan શું સાબિત કરી શકે
એક passive RLS scan Supabase દ્વારા https://[project].supabase.co/rest/v1/ પર expose કરેલા PostgREST endpoint સામે ચાલે છે. તે ફક્ત publishable anon key નો ઉપયોગ કરે છે — એ જ key જે તમારો browser ઉપયોગ કરે છે — અને table-list metadata, anonymous reads, અને anonymous writes માટે probe કરે છે. તે ક્યારેય user તરીકે authenticate નથી થતું અને ક્યારેય service-role privileges ને સ્પર્શ નથી કરતું. તે જે કંઈ કરી શકે છે, ઇન્ટરનેટ પર એક unauthenticated હુમલાખોર પણ કરી શકે છે.
database ની બહારથી, એક scanner નીચેનાને ઉચ્ચ વિશ્વાસ સાથે confirm કરી શકે છે:
- એક table પર RLS disabled છે. PostgREST anonymous
SELECTમાટે rows પાછી આપે છે જ્યારે RLS બંધ હોય અથવા જ્યારે policy તેને મંજૂરી આપે. બંને કિસ્સામાં તે એક finding છે. - Anonymous role tables list કરી શકે છે. anon key સાથેનું
GET /rest/v1/દરેક એ table માટે OpenAPI schema પાછી આપે છે જેના પરanonrole ને કોઈ privilege હોય. AI-generated apps વારંવાર schema પરUSAGEઅને દરેક table પરSELECTgrant કરે છે, જે વાસ્તવિક reads ને RLS deny કરે ત્યારે પણ સંપૂર્ણ schema map ને expose કરે છે. - Anonymous role insert કરી શકે છે. column shape ના અંદાજ સાથેનો probing
POSTસફળ થશે જો RLS પાસે તેને deny કરતીINSERTpolicy ન હોય — ભલેSELECTlocked down હોય. - Service-role key browser bundle માં છે. RLS ની નજીકનું: જો scanner ને JavaScript bundle માં
SUPABASE_SERVICE_ROLE_KEYઅથવાrole: service_roleધરાવતો કોઈ JWT મળે, તો RLS નકામો છે — એ key નો ધારક દરેક policy ને bypass કરે છે.
બાહ્ય scan શું સાબિત નથી કરી શકતું
Scanner ની સીમાઓ વિશે પ્રામાણિક રહો. એક બાહ્ય RLS scan તમારી pg_policies table, તમારી migration files, અથવા કોઈ policy નો ચોક્કસ predicate વાંચી શકતું નથી. તે black-box behaviour થી infer કરે છે, જેનો અર્થ છે કે તે કેટલીકવાર એવી finding report કરશે જે ઇરાદાપૂર્વકનો public data હોય (એક marketing newsletter table, એક public product catalog). FixVibe report આને medium confidence તરીકે flag કરે છે જ્યારે scanner ઈરાદાને અલગ ન કરી શકે — table નામ જુઓ અને નક્કી કરો.
ચાર તૂટેલા-RLS આકાર જે AI ટૂલ ઉત્પન્ન કરે છે
જ્યારે તમે Cursor, Claude Code, Lovable, અથવા Bolt ને Supabase પર નિર્દેશિત કરો છો, ત્યારે હજારો apps માં એ જ ચાર તૂટેલા-RLS pattern ઉભરી આવે છે. દરેક type-check પાસ કરે છે, compile થાય છે, અને ship થાય છે:
આકાર 1: RLS ક્યારેય enable થયું જ નહીં
સૌથી સામાન્ય failure mode. Migration table બનાવે છે પણ developer (અથવા AI ટૂલ) ALTER TABLE ... ENABLE ROW LEVEL SECURITY ભૂલી જાય છે. PostgREST ખુશીથી સંપૂર્ણ table anon key ધરાવતા કોઈને પણ આપે છે. Fix: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. FORCE વૈકલ્પિક નથી — તેના વગર table owner (અને table ownership ધરાવતી કોઈપણ role) RLS ને bypass કરે છે.
ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;આકાર 2: RLS enabled, કોઈ policies નહીં
વધુ સૂક્ષ્મ failure. RLS enabled છે પણ કોઈ policies લખાયેલી નથી. PostgreSQL માં ડિફોલ્ટ deny છે, તેથી authenticated users ને કંઈ દેખાતું નથી — અને developer app ને કામ કરાવવા માટે USING (true) ઉમેરે છે, જે દરેકને બધું વાંચવાની મંજૂરી આપે છે. Fix: એક policy લખો જે auth.uid() દ્વારા scope કરે: CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); અને એક અનુરૂપ INSERT/UPDATE/DELETE policy.
CREATE POLICY "select_own"
ON public.[name]
FOR SELECT
USING (auth.uid() = user_id);આકાર 3: Policy column ને પોતાની સાથે સરખાવે છે
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 પર policy પણ INSERT/UPDATE પર નહીં
Developer reads ને locked down કરે છે પણ writes ભૂલી જાય છે. RLS policies પ્રતિ-command છે. FOR SELECT ફક્ત reads ને protect કરે છે; એક anonymous client હજુ પણ INSERT કરી શકે છે જો કોઈ policy તેને deny ન કરે. Fix: પ્રતિ command એક policy લખો, અથવા explicit USING અને WITH CHECK clauses સાથે FOR ALL નો ઉપયોગ કરો.
FixVibe Supabase RLS scanner કેવી રીતે કામ કરે છે
baas.supabase-rls check ત્રણ તબક્કામાં ચાલે છે, દરેક સ્પષ્ટ confidence levels સાથે:
- તબક્કો 1 — fingerprint. Scanner deployed app ને crawl કરે છે, તેના JavaScript bundle ને parse કરે છે, અને runtime configuration માંથી Supabase project URL અને anon key કાઢે છે. કોઈ DNS guessing નહીં, કોઈ brute force નહીં — તે જે browser વાંચે છે તે વાંચે છે.
- તબક્કો 2 — schema discovery. anon key સાથેનું એક
GET /rest/v1/દરેક એ table માટે OpenAPI schema પાછી આપે છે જે anon role જોઈ શકે છે. Scanner table names રેકોર્ડ કરે છે પણ આ તબક્કે row data વાંચતું નથી. - તબક્કો 3 — read અને write probes. દરેક discovered table માટે, scanner
limit=1સાથે એક anonymousSELECTઈશ્યુ કરે છે. જો rows પાછી આવે, તો RLS permissive છે. Scanner ત્યાં અટકે છે — તે rows ની enumeration નથી કરતું, paginate નથી કરતું, ડેટાને modify નથી કરતું. INSERT probes verified domain ownership અને explicit opt-in પાછળ gated છે; તેઓ ક્યારેય unverified targets સામે fire નથી થતા.
દરેક finding ચોક્કસ request URL, response status, response shape (header-only), અને table name સાથે આવે છે. Finding ની તળિયે AI fix prompt એક copy-paste SQL block છે જે તમે Supabase SQL editor માં ચલાવો છો.
જ્યારે scanner કંઈક શોધે ત્યારે શું કરવું
દરેક RLS finding એક runtime કટોકટી છે. Public PostgREST endpoints મિનિટોમાં હુમલાખોરો દ્વારા scan થાય છે. Remediation sequence યાંત્રિક છે:
- દરેક table નું audit કરો. Supabase SQL editor માં
SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public';ચલાવો.rowsecurity = falseધરાવતી કોઈપણ row સમસ્યા છે. - દરેક public table પર RLS enable કરો. બનાવેલી દરેક table પર ડિફોલ્ટ રૂપે
ENABLE ROW LEVEL SECURITYઅનેFORCE ROW LEVEL SECURITYરાખો — તેને migration template બનાવો. - Policies command-by-command લખો.
FOR ALL USING (true)નો ઉપયોગ ન કરો. SELECT, INSERT, UPDATE, DELETE માટે explicit policies લખો — દરેકauth.uid()અથવાauth.jwt()માંથી org-id column પર scope કરેલી. - બીજા account સાથે verify કરો. અલગ user તરીકે sign up કરો, REST API મારફતે સીધા બીજા user ના records વાંચવાનો પ્રયાસ કરો. જો response
200હોય, તો policy તૂટી છે. - ફરી scan કરો. Fix લાગુ કર્યા પછી, એ જ URL સામે FixVibe scan ફરી ચલાવો.
baas.supabase-rlsfinding clear થવી જોઈએ.
-- 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;આ બીજા scanners સાથે કેવી રીતે સરખાવાય
મોટાભાગના generic DAST ટૂલ (Burp Suite, OWASP ZAP, Nessus) PostgREST શું છે તે જાણતા નથી. તેઓ તમારી app ને crawl કરશે, /rest/v1/ path ને અવગણશે, અને જે HTML pages તેઓ સમજે છે તેના પર report કરશે. Snyk અને Semgrep static-analysis ટૂલ છે — તેઓ તમારી repo માં ગુમ RLS calls સાથેની migration files શોધે છે, પણ તેઓ સાબિત નથી કરી શકતા કે deployed database ખોટી રીતે કોન્ફિગર થયેલ છે. FixVibe આ અંતરમાં બેસે છે: passive, BaaS-aware, એક unauthenticated હુમલાખોર public URL થી શું સાબિત કરી શકે તેના પર કેન્દ્રિત.
વારંવાર પૂછાતા પ્રશ્નો
શું scanner મારા data ને વાંચશે અથવા modify કરશે?
ના. Passive scans દરેક discovered table દીઠ વધુમાં વધુ એક SELECT ... limit=1 ઈશ્યુ કરે છે જે confirm કરે છે કે RLS anonymous reads ને મંજૂરી આપે છે કે નહીં. Scanner response shape રેકોર્ડ કરે છે, row contents નહીં. INSERT, UPDATE, અને DELETE probes verified domain ownership પાછળ gated છે અને ક્યારેય unverified targets સામે ચાલતા નથી.
જો મારો Supabase project paused હોય અથવા custom domain પર હોય તો શું આ કામ કરે છે?
Paused projects દરેક request પર 503 પાછી આપે છે — scanner project ને unreachable તરીકે report કરે છે. Custom domains ત્યાં સુધી કામ કરે છે જ્યાં સુધી deployed app browser માં Supabase client SDK લોડ કરે; scanner કોઈપણ રીતે bundle માંથી project URL કાઢે છે.
જો મારી anon key rotate થઈ જાય અથવા મારી publishable key બદલાઈ જાય તો શું?
Scan ફરી ચલાવો. Scanner દરેક run પર current bundle માંથી key ને ફરીથી કાઢે છે. Rotation ફક્ત અગાઉના report ને invalidate કરે છે, database ની policy state ને નહીં.
શું scanner નવા Supabase publishable-key model (<code>sb_publishable_*</code>) ને check કરે છે?
હા. Detector legacy anon JWTs અને નવી sb_publishable_* keys બંને ને ઓળખે છે અને તેમને સમાનરૂપે વર્તે છે — બંને public હોવાનો હેતુ ધરાવે છે અને બંને RLS ને defense ની એકમાત્ર line તરીકે છોડે છે.
આગળના પગલાં
તમારા production URL સામે મફત FixVibe scan ચલાવો — baas.supabase-rls check મફત tier સહિત દરેક plan પર enabled છે. Supabase project માંથી બીજું શું leak થઈ શકે તેના ઊંડા વાંચન માટે, Supabase service role key JavaScript માં ઉજાગર અને Supabase storage bucket security checklist જુઓ. બધા BaaS providers માં umbrella દૃશ્ય માટે, BaaS misconfiguration scanner વાંચો.
