FixVibe

// docs / baas security / supabase rls scanner

Supabase RLS სკანერი: იპოვეთ ცხრილები გამოტოვებული ან გაუმართავი row-level security-ით

Row-level security (RLS) არის ერთადერთი რამ, რაც დგას თქვენი მომხმარებლების მონაცემებსა და ინტერნეტს შორის, როდესაც თქვენ Supabase-ზე დაფუძნებულ აპს უშვებთ. AI-კოდირების ხელსაწყოები ქმნიან RLS-ფორმის კოდს, რომელიც კომპილირდება, იშვება და მონაცემებს ჩუმად ჟონავს — ცხრილები შექმნილია RLS-ის ჩართვის გარეშე, policy-ები, რომლებიც კითხულობენ მაგრამ არასოდეს ზღუდავენ, პრედიკატები, რომლებიც სვეტს თავის თავს ადარებენ. ეს სტატია გვიჩვენებს, რის დამტკიცებაც შეუძლია Supabase RLS-სკანერს გარედან, ოთხ გაუმართავ-RLS-ის ფორმას, რომელიც vibe-coded აპებში ჩნდება და როგორ დავასკანეროთ თქვენი საკუთარი დეპლოიმენტი წუთზე ნაკლებში.

რის დამტკიცებაც შეუძლია გარე RLS-სკანს

პასიური RLS-სკანი მუშაობს PostgREST-ის endpoint-ის წინააღმდეგ, რომელსაც Supabase ავლენს https://[project].supabase.co/rest/v1/-ზე. ის იყენებს მხოლოდ გამოსაქვეყნებელ anon გასაღებს — იმავე გასაღებს, რომელსაც თქვენი ბრაუზერი იყენებს — და ამოწმებს ცხრილების სიის მეტამონაცემებს, ანონიმურ წაკითხვებსა და ანონიმურ ჩაწერებს. ის არასოდეს ავთენტიფიცირდება როგორც მომხმარებელი და არასოდეს ეხება service-role პრივილეგიებს. ყველაფერი, რის გაკეთებაც მას შეუძლია, შეუძლია ინტერნეტში არსებულ არაავთენტიფიცირებულ თავდამსხმელსაც.

მონაცემთა ბაზის გარედან, სკანერი მაღალი დარწმუნებით ადასტურებს შემდეგს:

  • RLS ცხრილზე გათიშულია. PostgREST აბრუნებს მწკრივებს ანონიმური SELECT-ისთვის, როცა RLS გათიშულია ან როცა policy ნებას რთავს. ნებისმიერ შემთხვევაში ეს აღმოჩენაა.
  • ანონიმურ როლს შეუძლია ცხრილების ჩამოთვლა. GET /rest/v1/ anon-გასაღებით აბრუნებს OpenAPI-სქემას ყოველი ცხრილისთვის, რომელზეც anon როლს რაიმე პრივილეგია აქვს. AI-გენერირებული აპები ხშირად ანიჭებენ USAGE-ს სქემაზე და SELECT-ს ყოველ ცხრილზე, რაც ავლენს მთელ სქემის რუკას მაშინაც კი, როცა RLS აკრძალავს ფაქტობრივ წაკითხვებს.
  • ანონიმურ როლს შეუძლია ჩასმა. საცდელი POST სვეტის ფორმის ვარაუდით წარმატებული იქნება, თუ RLS-ს არ აქვს INSERT-policy, რომელიც მას უარყოფს — მაშინაც კი, თუ SELECT ჩაკეტილია.
  • service-role გასაღები ბრაუზერის ბანდლშია. RLS-თან მიმდებარედ: თუ სკანერი იპოვის SUPABASE_SERVICE_ROLE_KEY-ს ან ნებისმიერ JWT-ს role: service_role-ით JavaScript-ბანდლში, RLS აზრს კარგავს — ამ გასაღების მფლობელი გვერდს უვლის ყოველ policy-ს.

რის დამტკიცებაც გარე სკანს არ შეუძლია

იყავით პატიოსანი სკანერის საზღვრებთან მიმართებაში. გარე RLS-სკანს არ შეუძლია წაიკითხოს თქვენი pg_policies ცხრილი, თქვენი მიგრაციის ფაილები ან ნებისმიერი policy-ის ზუსტი პრედიკატი. ის ასკვნის შავი ყუთის ქცევიდან, რაც ნიშნავს, რომ ის ხანდახან მოახსენებს აღმოჩენას, რომელიც გამოდის რომ განზრახ საჯარო მონაცემია (მარკეტინგული newsletter-ის ცხრილი, საჯარო პროდუქტის კატალოგი). FixVibe-ის რეპორტი მათ აღნიშნავს როგორც საშუალო დარწმუნების, როცა სკანერს არ შეუძლია განზრახვის გარჩევა — დაათვალიერეთ ცხრილის სახელი და გადაწყვიტეთ.

ოთხი გაუმართავი-RLS-ის ფორმა, რომელსაც AI-ხელსაწყოები ქმნიან

როდესაც Cursor-ს, Claude Code-ს, Lovable-ს ან Bolt-ს Supabase-ზე მიმართავთ, ათასობით აპში ერთი და იგივე ოთხი გაუმართავი-RLS-ის შაბლონი ჩნდება. თითოეული მათგანი გადის type-check-ს, კომპილირდება და იშვება:

ფორმა 1: RLS არასოდეს ჩაირთო

ყველაზე გავრცელებული შეცდომის რეჟიმი. მიგრაცია ქმნის ცხრილს, მაგრამ დეველოპერი (ან AI-ხელსაწყო) ივიწყებს ALTER TABLE ... ENABLE ROW LEVEL SECURITY-ს. PostgREST ხალისით აწვდის მთელ ცხრილს ნებისმიერ ადამიანს, ვისაც anon-გასაღები აქვს. გასწორება: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. FORCE არ არის არჩევითი — მის გარეშე ცხრილის მფლობელი (და ნებისმიერი როლი ცხრილის მფლობელობით) გვერდს უვლის RLS-ს.

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

ფორმა 2: RLS ჩართულია, policy-ები არ არის

უფრო დახვეწილი შეცდომა. RLS ჩართულია, მაგრამ არც ერთი policy არ არის დაწერილი. ნაგულისხმევი ქცევა PostgreSQL-ში არის უარყოფა, ამიტომ ავთენტიფიცირებული მომხმარებლები ვერაფერს ხედავენ — და დეველოპერი ამატებს 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 — fingerprinting. სკანერი თვალს ადევნებს დეპლოიდ აპს, აანალიზებს მის JavaScript-ბანდლს და ამოიღებს Supabase-პროექტის URL-ს და anon-გასაღებს გაშვების კონფიგურაციიდან. არანაირი DNS-ვარაუდი, არანაირი brute force — ის კითხულობს იმას, რასაც ბრაუზერი კითხულობს.
  2. ეტაპი 2 — სქემის აღმოჩენა. ერთი GET /rest/v1/ anon-გასაღებით აბრუნებს OpenAPI-სქემას ყოველი ცხრილისთვის, რომელსაც anon-როლი ხედავს. სკანერი იწერს ცხრილების სახელებს, მაგრამ ამ ეტაპზე მწკრივების მონაცემებს არ კითხულობს.
  3. ეტაპი 3 — წაკითხვისა და ჩაწერის შემოწმებები. ყოველი აღმოჩენილი ცხრილისთვის სკანერი უშვებს ერთ ანონიმურ SELECT-ს limit=1-ით. თუ მწკრივები ბრუნდება, RLS დასაშვებია. სკანერი იქვე ჩერდება — ის არ ჩამოთვლის მწკრივებს, არ აქცევს ფურცლებად, არ ცვლის მონაცემებს. INSERT-შემოწმებები გადახდელია ვერიფიცირებული დომენის მფლობელობისა და ცხადი თანხმობის უკან; ისინი არასოდეს ეშვება არავერიფიცირებული მიზნების წინააღმდეგ.

ყოველი აღმოჩენა ცალ-ცალკე გადაეცემა ზუსტ მოთხოვნის URL-თან, პასუხის სტატუსთან, პასუხის ფორმასთან (მხოლოდ header) და ცხრილის სახელთან ერთად. AI-ფიქს-პრომპტი აღმოჩენის ბოლოში არის copy-paste SQL-ბლოკი, რომელსაც Supabase SQL-რედაქტორში გაუშვებთ.

რა უნდა გააკეთოთ, როცა სკანერი რამეს იპოვის

ყოველი RLS-აღმოჩენა საგანგებო რეჟიმის სიტუაციაა. საჯარო PostgREST-endpoint-ებს თავდამსხმელები წუთებში სკანერავენ. რემედიაციის თანამიმდევრობა მექანიკურია:

  1. აუდიტი გაუკეთეთ ყოველ ცხრილს. გაუშვით SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'; Supabase SQL-რედაქტორში. ნებისმიერი მწკრივი rowsecurity = false-ით პრობლემაა.
  2. ჩართეთ RLS ყოველ საჯარო ცხრილზე. ნაგულისხმევად დააწესეთ ENABLE ROW LEVEL SECURITY და FORCE ROW LEVEL SECURITY ყოველი შექმნილ ცხრილზე — გახადეთ ეს მიგრაციის შაბლონი.
  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 სტატიკურ-ანალიზის ხელსაწყოები არიან — ისინი იპოვიან მიგრაციის ფაილებს თქვენს რეპოში გამოტოვებული RLS-გამოძახებებით, მაგრამ ვერ დაამტკიცებენ, რომ დეპლოიდი მონაცემთა ბაზა არასწორად არის კონფიგურირებული. FixVibe ჯდება ხარვეზში: პასიური, BaaS-აზრიანი, ფოკუსირებული იმაზე, რის დამტკიცებაც არაავთენტიფიცირებულ თავდამსხმელს შეუძლია საჯარო URL-დან.

ხშირად დასმული შეკითხვები

სკანერი წაიკითხავს ან შეცვლის ჩემს მონაცემებს?

არა. პასიური სკანი უშვებს მაქსიმუმ ერთ SELECT ... limit=1-ს ყოველი აღმოჩენილი ცხრილისთვის, რომ დაადასტუროს, RLS ანონიმურ წაკითხვებს ნებას რთავს თუ არა. სკანერი იწერს პასუხის ფორმას, არა მწკრივის შინაარსს. INSERT-, UPDATE- და DELETE-შემოწმებები გადახდელია ვერიფიცირებული დომენის მფლობელობის უკან და არასოდეს ეშვება არავერიფიცირებული მიზნების წინააღმდეგ.

ეს იმუშავებს, თუ ჩემი Supabase-პროექტი შეჩერებულია ან კასტომ-დომენზეა?

შეჩერებული პროექტები აბრუნებენ 503-ს ყოველ მოთხოვნაზე — სკანერი მოახსენებს პროექტს როგორც მიუღწევადს. კასტომ-დომენები მუშაობს, თუ დეპლოიდი აპი ჯერ კიდევ ჩატვირთავს Supabase-კლიენტ-SDK-ს ბრაუზერში; სკანერი პროექტის URL-ს ბანდლიდან ამოიღებს ნებისმიერ შემთხვევაში.

რა მოხდება, თუ ჩემი anon-გასაღები შეიცვალა ან ჩემი გამოსაქვეყნებელი გასაღები იცვლება?

თავიდან გაუშვით სკანი. სკანერი თავიდან ამოიღებს გასაღებს მიმდინარე ბანდლიდან ყოველი გაშვებისას. ცვლა აუქმებს მხოლოდ წინა რეპორტს, არა მონაცემთა ბაზის policy-მდგომარეობას.

სკანერი ამოწმებს თუ არა Supabase-ის ახალ გამოსაქვეყნებელ-გასაღების მოდელს (<code>sb_publishable_*</code>)?

კი. დეტექტორი ცნობს როგორც მემკვიდრე anon JWT-ებს, ასევე ახალ sb_publishable_* გასაღებებს და ეპყრობა მათ იდენტურად — ორივე გათვლილია იყოს საჯარო და ორივე ტოვებს RLS-ს, როგორც დაცვის ერთადერთ ხაზს.

შემდეგი ნაბიჯები

გაუშვით უფასო FixVibe-სკანი თქვენი პროდუქციის URL-ის წინააღმდეგ — baas.supabase-rls შემოწმება ჩართულია ყოველ გეგმაში, უფასო ტარიფის ჩათვლით. იმაზე უფრო ღრმად, რა შეიძლება ჟონავდეს Supabase-პროექტიდან, ნახეთ Supabase service role გასაღების გამოვლენა JavaScript-ში და Supabase storage-ბაკეტის უსაფრთხოების სია. ყველა BaaS-პროვაიდერზე ერთიანი ხედვისთვის, წაიკითხეთ BaaS-ის არასწორი კონფიგურაციის სკანერი.

// დაასკანერეთ თქვენი baas-ზედაპირი

იპოვეთ ღია ცხრილი მანამ, სანამ ვინმე სხვა აღმოაჩენს.

შეიყვანეთ პროდუქციის URL. FixVibe აღმოაჩენს BaaS-პროვაიდერებს, რომლებსაც თქვენი აპი ესაუბრება, ამოიცნობს მათ საჯარო endpoint-ებს და გაცნობებთ, რის წაკითხვა ან ჩაწერა შეუძლია არაავთენტიფიცირებულ კლიენტს. უფასოდ, დაყენების გარეშე, ბარათის გარეშე.

  • უფასო ტარიფი — 3 სკანი თვეში, რეგისტრაციის ბარათის გარეშე.
  • პასიური BaaS-fingerprinting — დომენის ვერიფიკაცია არ არის საჭირო.
  • Supabase, Firebase, Clerk, Auth0, Appwrite და სხვები.
  • AI-ფიქს-პრომპტი ყოველი აღმოჩენისთვის — ჩასვით უკან Cursor-ში / Claude Code-ში.
უფასო BaaS-სკანის გაშვება

რეგისტრაცია არ არის საჭირო

Supabase RLS სკანერი: იპოვეთ ცხრილები გამოტოვებული ან გაუმართავი row-level security-ით — Docs · FixVibe