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 क्या साबित कर सकता है

A passive RLS scan looks at your Supabase project the way an anonymous visitor would. It uses only the publishable anon key — the same key your browser uses — and never authenticates as a user or touches service-role privileges. Anything it can see, an unauthenticated attacker on the internet can see.

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 उजागर कर देता है।
  • Read access does not establish write safety. A passive scan cannot prove that INSERT, UPDATE, or DELETE policies protect every user and tenant. Review write policies and test them with isolated fixtures under the intended roles.
  • 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 आकार बनाते हैं

When you point Cursor, Claude Code, Lovable, or Bolt at Supabase, the same four broken-RLS patterns come up again and again. Each one passes type-check, compiles, and ships:

आकार 1: RLS कभी enable नहीं किया गया

The most common failure mode. The migration creates the table but the developer (or the AI tool) forgets ALTER TABLE ... ENABLE ROW LEVEL SECURITY. PostgREST happily serves the entire table to anyone with the anon key. Fix: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY;, then add a policy per command. Enabling RLS with no policies denies all access through the API; the policies decide who gets in.

sql
ALTER TABLE public.[name] ENABLE 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 की तुलना खुद से करती है

एक copy-paste artefact। Developer USING (auth.uid() = user_id) के बजाय USING (user_id = user_id) लिखता है — जो हमेशा सत्य है। Type-checks पास होते हैं; policy हर row को अनुमति देती है। फ़िक्स: हमेशा column की तुलना एक function call (auth.uid(), auth.jwt()->>'org_id', आदि) से करें, कभी खुद से या किसी constant से नहीं।

Shape 4: Overly permissive write policies

With RLS enabled, a role with no applicable policy is denied by default. A SELECT policy does not itself allow INSERT. Write exposure can arise from a permissive applicable INSERT or ALL policy, disabled RLS, or a role that bypasses RLS. Fix: inspect table privileges and every applicable policy, use ownership-scoped WITH CHECK conditions, and test writes with separate user identities.

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

FixVibe's Supabase check works from the deployed app, in three steps:

  1. Find the project. FixVibe loads the deployed app and reads the Supabase project URL and public key from the same configuration your browser receives. No guessing, no brute force.
  2. See what is exposed. FixVibe checks which tables the anonymous role can see, without reading row data at this step.
  3. Stage 3 — inspect anonymous read access. The passive check reports observable access to discovered resources. It does not create, update, or delete database rows, and it cannot establish that all write policies or cross-user boundaries are correct.

Each finding ships with the exact request URL, response status, response shape (header-only), and the table name. FixVibe now labels whether the fix belongs in code/config, a provider console, DNS, secret rotation, or manual review so the next step matches who can actually apply it.

जब 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. Enable RLS on every public table. Default to ENABLE ROW LEVEL SECURITY on every table created — make it a 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. Re-scan. After applying the fix, re-run a FixVibe scan against the same URL. The Supabase RLS finding should clear.
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 करेगा?

The passive RLS check is read-only. It examines observable anonymous read access and reports limited evidence. It does not perform database write operations or prove that every user and tenant is correctly isolated.

क्या यह तब काम करता है जब मेरा 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 (sb_publishable_*) को check करता है?

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

अगले कदम

Run a free FixVibe scan against your production URL — the Supabase RLS check runs on every plan including the free tier. For a deeper read on what else can leak from a Supabase project, see Supabase service role key exposed in JavaScript and Supabase storage bucket security checklist. For the umbrella view across all BaaS providers, read 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 और अन्य।
  • Coding-agent prompts where code/config applies, plus provider-console steps for hosted BaaS fixes.
मुफ़्त BaaS scan चलाएँ →

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

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