TL;DR
“RLS Disabled in Public” (lint 0013_rls_disabled_in_public, taso ERROR) tarkoittaa, että julkaistun skeeman taulussa row level security on pois päältä samalla kun anon tai authenticated voi tehdä siihen selectin. Paikallisessa testissäni julkinen avain luki tällaisesta taulusta kaikki 3 riviä 3:sta ja lisäsi uuden vastauksella 201 Created. Ota RLS käyttöön, lisää politiikka jokaiselle operaatiolle ja tarkista oikeudet, kaikki yhdessä migraatiossa.
Rakensin ilmaisen Supabase-tietoturvatarkistuksen, ja sen ensimmäinen sääntö, “RLS pois päältä julkaistuissa tauluissa”, on sama löydös, jonka Supabasen Security Advisor raportoi virheenä. Se on yleisin aukko, jonka löydän tekoälytyökaluilla tehdyistä sovelluksista, joten tässä on, mitä se tarkoittaa ja mitä se salli, kun toistin sen.
Mitä “RLS disabled in public” tarkoittaa?
Security Advisor ajaa lintin nimeltä rls_disabled_in_public. Sen SQL liputtaa taulun, kun kolme asiaa pätee yhtä aikaa:
- Se on tavallinen taulu, jossa row level security on pois päältä.
- Roolilla
anontaiauthenticatedon siihenSELECT. - Sen skeema on Data API:n Exposed schemas -listalla, joka on oletuksena
public.
Lint-sivu luokittelee sen tasolle ERROR ja kutsuu täyttä create-, read-, update- ja delete-pääsyä internetin yli “a critically unsafe configuration”. Nimen “public” tarkoittaa skeemaa, mutta lint kattaa jokaisen julkaistun skeeman, siksi myös listalla oleva ylimääräinen skeema ansaitsee silmäyksen; kirjoitin siitä artikkelissa Supabase exposed schemas.
Mitä julkinen avain voi tehdä tällaiselle taululle?
Loin taulun orders kolmella tekaistulla asiakkaalla paikalliselle Supabase-stackille (CLI 2.109.1, Postgres 17.6, PostgREST 14.14) niillä oikeuksilla, jotka olemassa olevat projektit antavat uusille tauluille, ja RLS pois päältä. Sitten kutsuin Data API:a publishable keyllä niin kuin selain tekee:
| Pyyntö publishable keyllä | RLS pois | RLS päällä, ei politiikkaa |
|---|---|---|
GET /rest/v1/orders?select=* |
200, kaikki 3 riviä nimineen ja sähköposteineen |
200, [] |
POST /rest/v1/orders uudella rivillä |
201 Created |
401, 42501 “new row violates row-level security policy” |
Kuka tahansa, joka avaa sovelluksesi, voi kopioida publishable keyn sivulta. Kun RLS on pois päältä, avain on luku- ja kirjoitusoikeus kyseiseen tauluun.
Miten korjaat sen rikkomatta sovellusta?
Pelkkä RLS:n käyttöönotto saa taulun palauttamaan sovellukselle tyhjää, koska politiikkaa ei vielä ole. Silloin ihmiset, ja tekoälytyökalut, lisäävät politiikan using (true), joka palauttaa jokaisen rivin kaikille. Miksi update ja delete silloin ilmoittavat onnistuneensa, vaikka eivät muuta mitään, kerrotaan artikkelissa Enable RLS in Supabase: mitä taulu palauttaa sen jälkeen. Kirjoita oikeat politiikat samaan migraatioon:
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);
Jos taulun on tarkoitus olla julkinen, kuten julkaistujen artikkelien lista, pidä RLS silti päällä ja kirjoita yksi select-politiikka roolille anon, ilman kirjoitusoikeuksia. Jos et koskaan käytä Data API:a ja puhut Postgresille vain palvelimeltasi, poista public Exposed schemas -listalta, kuten Supabasen ylläpitäjät ehdottivat samassa issuessa.
Jotta uudet taulut eivät koskaan aloita ilman RLS:ää, Supabasen event triggers -oppaassa on trigger, joka ottaa sen käyttöön jokaisessa public-skeemaan luodussa taulussa. Ja 30. lokakuuta 2026 alkaen uudet taulut eivät saa oletuksena Data API -oikeuksia, joten ne vastaavat 42501, kunnes annat niille oikeudet; kävin sen läpi artikkelissa Supabase 42501 permission denied.
Mitä puhdas tulos ei todista?
Se, että RLS on päällä, ei kerro mitään siitä, ovatko politiikat oikein. Samassa testissä politiikka, joka oli kirjoitettu using (true), antoi julkiselle avaimelle taas kaikki 3 riviä, ja tämä lint pysyy hiljaa, kun RLS on kerran päällä. Tarkistuksessa on tälle oma sääntö, “Käytännöt, jotka päästävät läpi jokaisen rivin”, ja Supabase RLS:n testaus näyttää, miten todistat jokaisen politiikan oikeilla käyttäjillä. Aloituspolitiikat, jokainen ajettuna oikeita käyttäjiä vasten API:n kautta, löytyvät artikkelista Supabase RLS policy -esimerkit testattuna API:n kautta.