Pereiti prie turinio

Supabase „RLS disabled in public": ką tai reiškia

Supabase

Žiūrėti kaip MarkdownAtidaryti per ClaudeAtidaryti per ChatGPTAtidaryti per Perplexity

Klausimas taip pat nukopijuojamas. Jei pokalbis atsidaro tuščias, įklijuokite jį.

Trumpai

„RLS Disabled in Public” (lint 0013_rls_disabled_in_public, lygis ERROR) reiškia, kad atskleistos schemos lentelėje išjungtas row level security, o anon ar authenticated gali daryti select. Mano vietiniame teste viešasis raktas iš tokios lentelės perskaitė visas 3 eilutes iš 3 ir įterpė naują su 201 Created. Įjunkite RLS, pridėkite politiką kiekvienai operacijai ir patikrinkite teises, viską vienoje migracijoje.

Sukūriau nemokamą Supabase saugos tikrintuvą, o jo pirmoji taisyklė „RLS išjungtas atskleistose lentelėse” yra tas pats radinys, kurį Supabase Security Advisor praneša kaip klaidą. Tai dažniausia spraga, kurią randu su AI įrankiais sukurtose programose, todėl štai ką tai reiškia ir ką leido, kai tai atkartojau.

Ką reiškia „RLS disabled in public”?

Security Advisor paleidžia lint, vadinamą rls_disabled_in_public. Jo SQL pažymi lentelę, kai vienu metu teisingi trys dalykai:

  1. Tai paprasta lentelė su išjungtu row level security.
  2. anon ar authenticated turi jai SELECT.
  3. Jos schema yra Data API sąraše Exposed schemas, kuris pagal numatytuosius nustatymus yra public.

Lint puslapis jį vertina kaip ERROR, o visišką create, read, update ir delete prieigą internetu vadina „kritiškai nesaugia konfigūracija” („a critically unsafe configuration”). „Public” pavadinime yra schema, bet lint apima kiekvieną atskleistą schemą, todėl dėmesio vertas ir papildomas schemos įrašas tame sąraše; apie tai rašiau pastaboje Supabase exposed schemas.

Ką viešasis raktas gali padaryti tokiai lentelei?

Vietinėje Supabase aplinkoje (CLI 2.109.1, Postgres 17.6, PostgREST 14.14) sukūriau lentelę orders su trimis išgalvotais klientais, su teisėmis, kurias esami projektai suteikia naujoms lentelėms, ir išjungtu RLS. Tada kviečiau Data API su publishable key, kaip tai daro naršyklė:

Viena lentelė: RLS išjungtas ir įjungtas. Su viešuoju raktu, vietinis Supabase, 3 išgalvotų užsakymų eilutės. RLS išjungtas, skaitymas: Publishable key → orders, RLS išjungtas → 3 iš 3 eilučių; RLS išjungtas, įterpimas: Publishable key → orders, RLS išjungtas → 201 Created; RLS įjungtas, politikos dar nėra: Publishable key → orders, RLS įjungtas → 0 eilučių.
Mano atkartojimas vietiniame Supabase, 2026 m. spalio 23 d.
Užklausa su publishable key RLS išjungtas RLS įjungtas, politikos nėra
GET /rest/v1/orders?select=* 200, visos 3 eilutės su vardais ir el. paštais 200, []
POST /rest/v1/orders su nauja eilute 201 Created 401, 42501 „new row violates row-level security policy”

Kiekvienas, atidaręs jūsų programą, gali nukopijuoti publishable key iš puslapio. Kai RLS išjungtas, šis raktas yra skaitymo ir rašymo leidimas į tą lentelę.

Kaip tai ištaisyti nesugadinant programos?

Vien įjungus RLS lentelė programai nieko nebegrąžina, nes politikos dar nėra. Tame tuščiame ekrane žmonės ir AI įrankiai prideda politiką su using (true), kuri atiduoda visas eilutes visiems. Kodėl update ir delete tada praneša apie sėkmę, nieko nepakeisdami, aprašyta straipsnyje How to enable RLS in Supabase: ką grąžina API. Tikras politikas rašykite toje pačioje migracijoje:

alter table public.orders enable row level security;

revoke all on table public.orders from anon, authenticated;
grant select, insert on table public.orders to authenticated;

create policy "Customers read their orders"
on public.orders for select
to authenticated
using ((select auth.uid()) = user_id);

create policy "Customers create their orders"
on public.orders for insert
to authenticated
with check ((select auth.uid()) = user_id);

Jei lentelė skirta būti vieša, pavyzdžiui, paskelbtų straipsnių sąrašas, vis tiek palikite RLS įjungtą ir parašykite vieną select politiką rolei anon, be rašymo teisių. Jei Data API niekada nenaudojate ir su Postgres kalbatės tik iš savo serverio, vietoj to pašalinkite public iš Exposed schemas, kaip Supabase prižiūrėtojai pasiūlė tame pačiame issue.

Kad naujos lentelės niekada nepradėtų be RLS, Supabase event triggers vadove yra trigeris, įjungiantis jį kiekvienoje schemoje public sukurtoje lentelėje. O nuo 2026 m. spalio 30 d. naujos lentelės pagal numatytuosius nustatymus negauna Data API teisių, todėl atsako 42501, kol teisių nesuteikiate; tai aprašiau pastaboje Supabase 42501 permission denied.

Ko švarus rezultatas neįrodo?

Tai, kad RLS įjungtas, nieko nesako apie tai, ar politikos teisingos. Tame pačiame teste politika using (true) viešajam raktui vėl atidavė visas 3 eilutes, o šis lint tyli, kai tik RLS įjungtas. Tikrintuvas tam turi atskirą taisyklę, „Politikos, leidžiančios visas eilutes“, o kaip testuoju Supabase RLS parodo, kaip kiekvieną politiką įrodyti su tikrais vartotojais. Politikos, nuo kurių galite pradėti, kiekviena išbandyta su tikrais vartotojais per API, pateiktos straipsnyje Supabase RLS policy: pavyzdžiai, išbandyti per API.

© 2026 Denys Zaichenko. Originalus straipsnis: https://madsalt.tech/lt/notes/supabase-rls-disabled-in-public/