FixVibe

// docs / baas security / supabase rls scanner

Supabase RLS scanner: गायब या टूटी row-level security वाली tables ढूँढ़ें

जब आप एक Supabase-समर्थित app ship करते हैं, तो आपके ग्राहकों के डेटा और इंटरनेट के बीच Row-level security (RLS) ही एकमात्र बाधा होती है। AI कोडिंग टूल ऐसा RLS-आकार का कोड बनाते हैं जो compile होता है, ship होता है, और चुपचाप डेटा लीक करता है — 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 लौटाता है जिस पर anon role को कोई privilege है। AI-generated apps अक्सर schema पर USAGE और हर table पर SELECT grant करती हैं, जो असली reads को RLS deny करने पर भी पूरा schema map उजागर कर देता है।
  • Anonymous role insert कर सकता है। column shape के अनुमान के साथ एक probing POST सफल हो जाएगा यदि RLS के पास इसे deny करने वाली कोई INSERT policy नहीं है — भले ही SELECT locked 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 से अनुमान लगाता है, जिसका अर्थ है कि यह कभी-कभी ऐसी finding रिपोर्ट करेगा जो वास्तव में जानबूझकर public data हो (एक marketing newsletter table, एक public product catalog)। जब scanner intent स्पष्ट नहीं कर सकता तो FixVibe report इन्हें medium confidence के रूप में फ़्लैग करती है — table नाम की समीक्षा करें और तय करें।

AI टूल जो चार टूटी-RLS आकार बनाते हैं

जब आप 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 anon key वाले किसी को भी पूरी table खुशी-खुशी serve कर देता है। फ़िक्स: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;। FORCE optional नहीं है — इसके बिना table owner (और table ownership वाला कोई भी role) RLS को bypass कर देता है।

sql
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 में default deny है, इसलिए authenticated users को कुछ नहीं दिखता — और developer app काम करने के लिए USING (true) जोड़ देता है, जो हर किसी को सब कुछ पढ़ने की अनुमति देता है। फ़िक्स: ऐसी policy लिखें जो auth.uid() द्वारा scoped हो: CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); और एक matching INSERT/UPDATE/DELETE policy।

sql
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 per-command होती हैं। FOR SELECT केवल reads की सुरक्षा करता है; एक anonymous client अभी भी INSERT कर सकता है यदि कोई policy इसे deny नहीं करती। फ़िक्स: per command एक policy लिखें, या स्पष्ट USING और WITH CHECK clauses के साथ FOR ALL का उपयोग करें।

FixVibe Supabase RLS scanner कैसे काम करता है

baas.supabase-rls check तीन चरणों में चलता है, हर एक स्पष्ट confidence levels के साथ:

  1. चरण 1 — fingerprint. Scanner deployed app को crawl करता है, इसके JavaScript bundle को parse करता है, और runtime कॉन्फ़िगरेशन से Supabase project URL और anon key निकालता है। कोई DNS अनुमान नहीं, कोई brute force नहीं — यह वही पढ़ता है जो browser पढ़ता है।
  2. चरण 2 — schema discovery. anon key के साथ एक एकल GET /rest/v1/ हर उस table के लिए OpenAPI schema लौटाता है जिसे anon role देख सकता है। Scanner table नाम record करता है पर इस चरण में row data नहीं पढ़ता।
  3. चरण 3 — read और write probes. प्रत्येक खोजी गई table के लिए, scanner limit=1 के साथ एक anonymous SELECT issue करता है। यदि rows लौटती हैं, तो RLS permissive है। Scanner वहीं रुक जाता है — यह rows को enumerate नहीं करता, paginate नहीं करता, data modify नहीं करता। INSERT probes verified domain ownership और स्पष्ट opt-in के पीछे gated हैं; ये कभी भी unverified targets के विरुद्ध fire नहीं होते।

हर finding सटीक request URL, response status, response shape (केवल header), और table नाम के साथ ship होती है। Finding के नीचे AI fix prompt एक copy-paste SQL block है जिसे आप Supabase SQL editor में चलाते हैं।

जब scanner कुछ ढूँढ़ ले तो क्या करें

हर RLS finding एक runtime emergency है। Public PostgREST endpoints को हमलावर मिनटों में scan कर लेते हैं। Remediation sequence यांत्रिक है:

  1. हर table का audit करें। Supabase SQL editor में SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'; चलाएँ। rowsecurity = false वाली कोई भी row एक समस्या है।
  2. हर public table पर RLS enable करें। बनाई गई हर table पर ENABLE ROW LEVEL SECURITY और FORCE ROW LEVEL SECURITY को default बनाएँ — इसे एक migration template बना दें।
  3. Policies को command-by-command लिखें। FOR ALL USING (true) का उपयोग न करें। SELECT, INSERT, UPDATE, DELETE के लिए स्पष्ट policies लिखें — हर एक auth.uid() या auth.jwt() से एक org-id column पर scoped हो।
  4. एक दूसरे account से verify करें। एक अलग user के रूप में sign up करें, सीधे REST API के माध्यम से किसी अन्य user के records को पढ़ने का प्रयास करें। यदि response 200 है, तो policy टूटी हुई है।
  5. दोबारा scan करें। फ़िक्स लागू करने के बाद, उसी URL के विरुद्ध FixVibe scan फिर से चलाएँ। baas.supabase-rls finding साफ़ हो जानी चाहिए।
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;

यह अन्य scanners की तुलना में कैसा है

अधिकांश सामान्य 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 प्रत्येक खोजी गई table के लिए अधिकतम एक SELECT ... limit=1 issue करते हैं ताकि यह confirm किया जा सके कि RLS anonymous reads की अनुमति देता है या नहीं। Scanner response shape record करता है, 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 load करती है; scanner किसी भी तरह से bundle से project URL निकाल लेता है।

क्या होगा यदि मेरी anon key rotate हो जाती है या मेरी publishable key बदल जाती है?

Scan फिर से चलाएँ। Scanner हर run पर current bundle से key को फिर से निकालता है। Rotation केवल पिछली report को अमान्य करता है, database की policy state को नहीं।

क्या scanner नए Supabase publishable-key model (<code>sb_publishable_*</code>) को check करता है?

हाँ। Detector legacy anon JWTs और नई sb_publishable_* keys दोनों को पहचानता है और उन्हें समान रूप से treat करता है — दोनों public होने के लिए हैं और दोनों RLS को रक्षा की एकमात्र पंक्ति के रूप में छोड़ते हैं।

अगले कदम

अपने production URL के विरुद्ध एक मुफ़्त FixVibe scan चलाएँ — baas.supabase-rls check मुफ़्त tier सहित हर plan पर enabled है। Supabase project से और क्या लीक हो सकता है, इस पर गहन पढ़ने के लिए, JavaScript में Supabase service role key उजागर और Supabase storage bucket security checklist देखें। सभी BaaS providers में umbrella दृश्य के लिए, BaaS misconfiguration scanner पढ़ें।

// अपनी baas सतह को scan करें

किसी और के पहले खुली table खोजें।

एक प्रोडक्शन URL डालें। FixVibe उन BaaS providers की गिनती करता है जिनसे आपकी app बात करती है, उनके public endpoints का fingerprint लेता है, और बताता है कि एक unauthenticated client क्या पढ़ या लिख सकता है। मुफ़्त, बिना इंस्टॉल, बिना कार्ड।

  • मुफ़्त tier — 3 scans / माह, साइनअप के लिए कार्ड नहीं चाहिए।
  • Passive BaaS fingerprinting — domain verification की ज़रूरत नहीं।
  • Supabase, Firebase, Clerk, Auth0, Appwrite और अन्य।
  • हर finding पर AI fix prompts — Cursor / Claude Code में paste करें।
मुफ़्त BaaS scan चलाएँ

साइनअप की आवश्यकता नहीं

Supabase RLS scanner: गायब या टूटी row-level security वाली tables ढूँढ़ें — Docs · FixVibe