FixVibe

// docs / baas security / supabase rls scanner

Supabase RLS սկաներ․ գտիր table-ներ, որոնք չունեն կամ ունեն կոտրված row-level security

Row-level security-ն (RLS) միակ բանն է, որ կանգնած է քո հաճախորդների տվյալների և համացանցի միջև, երբ դու թողարկում ես Supabase-ով աջակցվող հավելված։ AI-ի կոդավորման գործիքները գեներացնում են RLS-ի տեսք ունեցող կոդ, որ կոմպիլյացվում, թողարկվում և լուռ արտահոսում է տվյալները — table-ներ ստեղծված առանց RLS-ի միացման, policy-ներ, որ կարդում են, բայց երբեք չեն սահմանափակում, պրեդիկատներ, որ սյունակը համեմատում են ինքն իր հետ։ Այս հոդվածը ցույց է տալիս՝ ինչ կարող է ապացուցել Supabase RLS սկաները դրսից, vibe-coded հավելվածներում երևացող կոտրված-RLS-ի չորս ձևերը, և ինչպես սկանավորել քո սեփական deployment-ն ավելի քան մեկ րոպեի ընթացքում։

Ինչ կարող է ապացուցել արտաքին RLS սկանը

Պասիվ RLS սկանն աշխատում է PostgREST endpoint-ի դեմ, որը Supabase-ը բացում է https://[project].supabase.co/rest/v1/ հասցեում։ Այն օգտագործում է միայն հանրային anon բանալին — նույնը, որ քո զննարկիչն է օգտագործում — և ստուգում է table-ի մետատվյալների ցանկը, անանուն ընթերցումները և անանուն գրառումները։ Այն երբեք չի վավերացվում որպես օգտատեր և երբեք չի դիպչում service-role արտոնություններին։ Այն ամենը, ինչ կարող է անել, կարող է անել նաև համացանցում չհաստատված հարձակվողը։

Տվյալների բազայից դուրս՝ սկաները կարող է բարձր վստահությամբ հաստատել հետևյալը․

  • RLS-ն անջատված է table-ի վրա։ PostgREST-ը տողեր է վերադարձնում անանուն SELECT-ի համար, երբ RLS-ն անջատված է կամ երբ policy-ն թույլատրում է։ Երկու դեպքն էլ գտածո է։
  • Անանուն դերը կարող է թվարկել table-ները։ GET /rest/v1/-ը anon բանալիով վերադարձնում է OpenAPI սխեմա յուրաքանչյուր table-ի համար, որի վրա anon դերն ունի որևէ արտոնություն։ AI-ով գեներացված հավելվածները հաճախ տալիս են USAGE սխեմայի վրա և SELECT ամեն table-ի վրա, ինչը բացահայտում է ամբողջ սխեման, նույնիսկ երբ RLS-ն արգելում է իրական ընթերցումները։
  • Անանուն դերը կարող է insert անել։ Ստուգող POST-ը՝ սյունակների ձևի ենթադրությամբ, կհաջողվի, եթե RLS-ը չունի INSERT արգելող policy — նույնիսկ եթե SELECT-ը փակ է։
  • Service-role բանալին զննարկիչի bundle-ում է։ RLS-ին հարակից․ եթե սկաները գտնում է SUPABASE_SERVICE_ROLE_KEY կամ որևէ JWT՝ role: service_role պարունակությամբ, JavaScript bundle-ում, RLS-ն իմաստ չունի — այդ բանալին պահողը շրջանցում է ցանկացած policy։

Ինչը չի կարող ապացուցել արտաքին սկանը

Ազնիվ եղիր սկաների սահմանների հետ։ Արտաքին RLS սկանը չի կարող կարդալ քո pg_policies table-ը, քո migration ֆայլերը կամ որևէ policy-ի ճշգրիտ պրեդիկատը։ Այն եզրակացնում է սև-արկղային վարքից, ինչը նշանակում է, որ երբեմն կհայտնի գտածո, որը պարզվի, որ դիտավորյալ հանրային տվյալ է (մարքեթինգային newsletter table, հանրային ապրանքների կատալոգ)։ FixVibe-ի հաշվետվությունը դրանք նշում է որպես միջին վստահության, երբ սկաները չի կարող պարզել դիտավորությունը — ստուգիր table-ի անունը և որոշիր։

AI գործիքների արտադրած կոտրված-RLS-ի չորս ձևերը

Երբ դու Cursor, Claude Code, Lovable կամ Bolt ուղղորդում ես Supabase-ի վրա, նույն չորս կոտրված-RLS նմուշները ի հայտ են գալիս հազարավոր հավելվածներում։ Ամեն մեկն անցնում է type-check-ը, կոմպիլյացվում և թողարկվում է․

Ձև 1․ RLS երբեք չմիացված

Ամենատարածված ձախողման ռեժիմը։ Migration-ը ստեղծում է table-ը, բայց ծրագրավորողը (կամ AI գործիքը) մոռանում է ALTER TABLE ... ENABLE ROW LEVEL SECURITY։ PostgREST-ը ուրախությամբ սպասարկում է ամբողջ table-ը anon բանալի ունեցող ցանկացածին։ Շտկում․ ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;։ FORCE-ը պարտադիր է — առանց դրա table-ի սեփականատերը (և սեփականության դեր ունեցող ցանկացած role) շրջանցում է RLS-ը։

sql
ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.[name] FORCE  ROW LEVEL SECURITY;

Ձև 2․ RLS միացված, policy-ներ չկան

Ավելի նուրբ ձախողում։ RLS-ը միացված է, բայց policy-ներ գրված չեն։ PostgreSQL-ում լռելյայնը deny-ն է, ուստի վավերացված օգտատերերը ոչինչ չեն տեսնում — և ծրագրավորողն ավելացնում է USING (true), որ հավելվածն աշխատի, ինչը թույլ է տալիս բոլորին կարդալ ամեն ինչ։ Շտկում․ գրիր policy, որ սահմանափակում է auth.uid()-ով․ CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); և համապատասխան INSERT/UPDATE/DELETE policy։

sql
CREATE POLICY "select_own"
  ON public.[name]
  FOR SELECT
  USING (auth.uid() = user_id);

Ձև 3․ Policy-ն սյունակը համեմատում է ինքն իր հետ

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․ Policy-ն SELECT-ի վրա, բայց ոչ INSERT/UPDATE-ի

Ծրագրավորողը փակում է ընթերցումները, բայց մոռանում գրառումները։ RLS policy-ները հրամանի մակարդակով են։ FOR SELECT-ը պաշտպանում է միայն ընթերցումները. անանուն հաճախորդը կարող է դեռ INSERT անել, եթե ոչ մի policy չի արգելում։ Շտկում․ գրիր policy յուրաքանչյուր հրամանի համար կամ օգտագործիր FOR ALL բացահայտ USING և WITH CHECK պայմաններով։

Ինչպես է աշխատում FixVibe-ի Supabase RLS սկաները

baas.supabase-rls ստուգումն աշխատում է երեք փուլով, յուրաքանչյուրը՝ բացահայտ վստահության մակարդակներով․

  1. Փուլ 1 — fingerprint։ Սկաները քայլում է թողարկված հավելվածով, վերլուծում նրա JavaScript bundle-ը և runtime կարգավորումից հանում Supabase project URL-ն ու anon բանալին։ Ոչ DNS-ի կռահում, ոչ brute force — այն կարդում է այն, ինչ զննարկիչն է կարդում։
  2. Փուլ 2 — սխեմայի հայտնաբերում։ Մեկ GET /rest/v1/-ը anon բանալիով վերադարձնում է OpenAPI սխեմա յուրաքանչյուր table-ի համար, որ anon դերը կարող է տեսնել։ Սկաները գրառում է table-ի անունները, բայց այս փուլում չի կարդում տողերի տվյալները։
  3. Փուլ 3 — ընթերցման և գրառման ստուգումներ։ Յուրաքանչյուր հայտնաբերված table-ի համար սկաներն ուղարկում է մեկ անանուն SELECT limit=1-ով։ Եթե տողեր են վերադառնում, RLS-ը թույլտու է։ Սկաներն այնտեղ կանգ է առնում — այն չի թվարկում տողերը, չի էջագնում, չի փոփոխում տվյալները։ INSERT ստուգումները սահմանափակված են հաստատված տիրույթի սեփականությամբ և բացահայտ թույլտվությամբ. դրանք երբեք չեն աշխատում չհաստատված թիրախների դեմ։

Յուրաքանչյուր գտածո ուղեկցվում է ճշգրիտ հարցման URL-ով, պատասխանի կարգավիճակով, պատասխանի ձևով (միայն վերնագիր) և table-ի անունով։ AI fix prompt-ը գտածոյի ներքևում պատճենահան-տեղադրման SQL block է, որը գործարկում ես Supabase SQL editor-ում։

Ինչ անել, երբ սկաները ինչ-որ բան է գտնում

Յուրաքանչյուր RLS գտածո runtime արտակարգ իրավիճակ է։ Հանրային PostgREST endpoint-ները հարձակվողների կողմից սկանավորվում են րոպեների ընթացքում։ Շտկման հաջորդականությունը մեխանիկական է․

  1. Աուդիտ արա ամեն table-ը։ Գործարկիր SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'; Supabase SQL editor-ում։ Ցանկացած տող rowsecurity = false-ով խնդիր է։
  2. Միացրու RLS-ը յուրաքանչյուր հանրային table-ի վրա։ Լռելյայն դարձրու ENABLE ROW LEVEL SECURITY և FORCE ROW LEVEL SECURITY ստեղծվող յուրաքանչյուր table-ի վրա — դարձրու դա migration template։
  3. Գրիր policy-ները հրաման-առ-հրաման։ Մի օգտագործիր FOR ALL USING (true)։ Գրիր բացահայտ policy-ներ SELECT-ի, INSERT-ի, UPDATE-ի, DELETE-ի համար — ամեն մեկը սահմանված auth.uid()-ով կամ auth.jwt()-ից org-id սյունակով։
  4. Ստուգիր երկրորդ հաշվով։ Գրանցվիր որպես այլ օգտատեր, փորձիր կարդալ մեկ այլ օգտատիրոջ գրառումները REST API-ի միջոցով ուղղակիորեն։ Եթե պատասխանը 200 է, policy-ն կոտրված է։
  5. Կրկին սկանավորիր։ Շտկումը կիրառելուց հետո կրկին գործարկիր FixVibe սկանը նույն URL-ի դեմ։ baas.supabase-rls գտածոն պետք է մաքրվի։
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;

Ինչպես է սա համեմատվում այլ սկաների հետ

Ընդհանուր DAST գործիքների մեծ մասը (Burp Suite, OWASP ZAP, Nessus) չգիտի, թե ինչ է PostgREST-ը։ Նրանք կքայլեն քո հավելվածով, կանտեսեն /rest/v1/ ուղին և կհաշվետվեն այն HTML էջերի մասին, որ հասկանում են։ Snyk-ն ու Semgrep-ը ստատիկ վերլուծության գործիքներ են — նրանք գտնում են migration ֆայլեր քո repo-ում՝ բացակայող RLS կանչերով, բայց չեն կարող ապացուցել, որ թողարկված տվյալների բազան սխալ կարգավորված է։ FixVibe-ը գտնվում է բացում․ պասիվ, BaaS-ի մասին տեղյակ, կենտրոնացած այն բանի վրա, ինչ չհաստատված հարձակվողը կարող է ապացուցել հանրային URL-ից։

Հաճախակի տրվող հարցեր

Կկարդա՞ կամ կփոփոխի՞ իմ տվյալները սկաները։

Ոչ։ Պասիվ սկանները ուղարկում են առավելագույնը մեկ SELECT ... limit=1 հայտնաբերված table-ի համար՝ հաստատելու, թե արդյոք RLS-ը թույլատրում է անանուն ընթերցումներ։ Սկաները գրառում է պատասխանի ձևը, ոչ թե տողի բովանդակությունը։ INSERT, UPDATE և DELETE ստուգումները սահմանափակված են հաստատված տիրույթի սեփականությամբ և երբեք չեն աշխատում չհաստատված թիրախների դեմ։

Կաշխատի՞ սա, եթե իմ Supabase նախագիծը դադարեցված է կամ հատուկ տիրույթում։

Դադարեցված նախագծերը վերադարձնում են 503 յուրաքանչյուր հարցման համար — սկաները հաշվետու է, որ նախագիծն անհասանելի է։ Հատուկ տիրույթներն աշխատում են, քանի դեռ թողարկված հավելվածը դեռ բեռնում է Supabase client SDK-ն զննարկիչում. սկաները հանում է project URL-ը bundle-ից ամեն դեպքում։

Իսկ եթե իմ anon բանալին պտտվում է կամ իմ հանրային բանալին փոխվում է։

Կրկին գործարկիր սկանը։ Սկաները ամեն գործարկման ժամանակ վերահանում է բանալին ընթացիկ bundle-ից։ Պտտումն անվավեր է դարձնում միայն նախորդ հաշվետվությունը, ոչ թե տվյալների բազայի policy-ի վիճակը։

Ստուգո՞ւմ է սկաները Supabase-ի նոր publishable-key մոդելը (<code>sb_publishable_*</code>)։

Այո։ Դետեկտորը ճանաչում է և՛ ժառանգային anon JWT-ները, և՛ ավելի նոր sb_publishable_* բանալիները ու դրանք վերաբերվում է նույնականորեն — երկուսն էլ նախատեսված են հանրային լինելու համար և երկուսն էլ թողնում են RLS-ը որպես պաշտպանության միակ գիծ։

Հաջորդ քայլեր

Գործարկիր անվճար FixVibe սկան քո production URL-ի դեմ — baas.supabase-rls ստուգումը միացված է բոլոր փաթեթներում՝ ներառյալ անվճարը։ Ավելի խորը կարդալու համար այն մասին, թե էլ ինչ կարող է արտահոսել Supabase նախագծից, տես Supabase service role key-ի բացահայտում JavaScript-ում և Supabase storage bucket-ի անվտանգության ստուգաթերթ։ Բոլոր BaaS մատակարարների միասնական տեսքի համար կարդա BaaS սխալ կարգավորման սկաներ։

// սկանավորիր քո baas մակերեսը

Գտիր բաց table-ը, քանի դեռ դա ուրիշը չի արել։

Մուտքագրիր production URL-ը։ FixVibe-ը թվարկում է BaaS մատակարարները, որոնց հետ խոսում է քո հավելվածը, ֆինգերփրինթ է անում իրենց հանրային endpoint-ները, և հայտնում, թե ինչ կարող է կարդալ կամ գրել չհաստատված հաճախորդը։ Անվճար, առանց տեղադրման, առանց քարտի։

  • Անվճար փաթեթ — 3 սկան ամսական, առանց գրանցման քարտի։
  • Պասիվ BaaS fingerprinting — տիրույթի հաստատում չի պահանջվում։
  • Supabase, Firebase, Clerk, Auth0, Appwrite և ավելին։
  • AI fix prompts յուրաքանչյուր գտածոյի համար — տեղադրիր Cursor / Claude Code-ում։
Գործարկիր անվճար BaaS սկան

գրանցում չի պահանջվում

Supabase RLS սկաներ․ գտիր table-ներ, որոնք չունեն կամ ունեն կոտրված row-level security — Docs · FixVibe