FixVibe

// docs / baas security / supabase rls scanner

Escàner de RLS de Supabase: detecta taules amb seguretat a nivell de fila absent o trencada

La seguretat a nivell de fila (RLS) és l'única cosa que s'interposa entre les dades dels teus clients i internet quan publiques una aplicació recolzada en Supabase. Les eines de codificació amb IA generen codi amb forma de RLS que compila, es publica i filtra dades en silenci — taules creades sense RLS habilitat, polítiques que llegeixen però no restringeixen mai, predicats que comparen una columna amb si mateixa. Aquest article mostra què pot demostrar un escàner de RLS de Supabase des de fora, les quatre formes de RLS trencada que apareixen en aplicacions generades amb IA i com escanejar el teu propi desplegament en menys d'un minut.

Què pot demostrar un escaneig de RLS extern

Un escaneig de RLS passiu s'executa contra l'endpoint PostgREST que Supabase exposa a https://[project].supabase.co/rest/v1/. Només fa servir la clau anon publicable — la mateixa que fa servir el teu navegador — i sondeja les metadades de llistat de taules, les lectures anònimes i les escriptures anònimes. Mai s'autentica com a usuari i mai toca els privilegis de rol de servei. Qualsevol cosa que pugui fer, un atacant no autenticat a internet també la pot fer.

Des de fora de la base de dades, un escàner pot confirmar el següent amb alta confiança:

  • RLS està deshabilitat en una taula. PostgREST retorna files per a un SELECT anònim quan RLS està desactivat o quan una política ho permet. Qualsevol dels dos casos és una troballa.
  • El rol anònim pot llistar taules. Un GET /rest/v1/ amb la clau anon retorna l'esquema OpenAPI de cada taula sobre la qual el rol anon tingui qualsevol privilegi. Les aplicacions generades amb IA sovint atorguen USAGE sobre l'esquema i SELECT sobre cada taula, fet que exposa el mapa complet de l'esquema fins i tot quan RLS denega les lectures reals.
  • El rol anònim pot inserir. Un POST de sondeig amb una conjectura sobre la forma de les columnes tindrà èxit si RLS no té una política INSERT que ho negui — fins i tot si SELECT està bloquejat.
  • La clau de rol de servei és al bundle del navegador. Adjacent a RLS: si un escàner troba SUPABASE_SERVICE_ROLE_KEY o qualsevol JWT amb role: service_role al bundle de JavaScript, RLS no importa — qui tingui aquesta clau es pot saltar qualsevol política.

Què no pot demostrar un escaneig extern

Sigues honest sobre els límits de l'escàner. Un escaneig de RLS extern no pot llegir la teva taula pg_policies, els teus fitxers de migració ni el predicat exacte de cap política. Infereix a partir del comportament de caixa negra, fet que vol dir que de vegades informarà d'una troballa que resulta ser dades públiques intencionades (una taula de butlletí de màrqueting, un catàleg públic de productes). L'informe de FixVibe les marca com a confiança mitjana quan l'escàner no pot determinar la intenció — revisa el nom de la taula i decideix.

Les quatre formes de RLS trencada que produeixen les eines d'IA

Quan apuntes Cursor, Claude Code, Lovable o Bolt cap a Supabase, els mateixos quatre patrons de RLS trencada emergeixen en milers d'aplicacions. Cadascun passa la verificació de tipus, compila i es publica:

Forma 1: RLS mai habilitat

El mode de fallida més comú. La migració crea la taula però el desenvolupador (o l'eina d'IA) oblida ALTER TABLE ... ENABLE ROW LEVEL SECURITY. PostgREST serveix de gust la taula sencera a qualsevol amb la clau anon. Solució: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. FORCE no és opcional — sense ell, el propietari de la taula (i qualsevol rol amb propietat de taula) se salta RLS.

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

Forma 2: RLS habilitat, sense polítiques

Una fallida més subtil. RLS està habilitat però no s'ha escrit cap política. El predeterminat a PostgreSQL és denegar, així que els usuaris autenticats no veuen res — i el desenvolupador afegeix USING (true) perquè l'aplicació funcioni, fet que permet que tothom ho llegeixi tot. Solució: escriu una política que delimiti per auth.uid(): CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); i una política INSERT/UPDATE/DELETE corresponent.

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

Forma 3: La política compara la columna amb si mateixa

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.

Forma 4: Política a SELECT però no a INSERT/UPDATE

El desenvolupador bloqueja les lectures però oblida les escriptures. Les polítiques RLS són per comanda. FOR SELECT només protegeix les lectures; un client anònim encara pot INSERT si cap política ho denega. Solució: escriu una política per comanda, o fes servir FOR ALL amb clàusules explícites USING i WITH CHECK.

Com funciona l'escàner de RLS de Supabase de FixVibe

La comprovació baas.supabase-rls s'executa en tres etapes, cadascuna amb nivells de confiança explícits:

  1. Etapa 1 — identificació. L'escàner rastreja l'aplicació desplegada, analitza el seu bundle de JavaScript i extreu l'URL del projecte Supabase i la clau anon de la configuració en temps d'execució. Sense endevinalles de DNS, sense força bruta — llegeix el mateix que llegeix el navegador.
  2. Etapa 2 — descobriment de l'esquema. Un únic GET /rest/v1/ amb la clau anon retorna l'esquema OpenAPI de cada taula que el rol anon pugui veure. L'escàner registra els noms de les taules però no llegeix les dades de les files en aquesta etapa.
  3. Etapa 3 — sondejos de lectura i escriptura. Per a cada taula descoberta, l'escàner emet un SELECT anònim amb limit=1. Si retornen files, RLS és permissiu. L'escàner s'atura aquí — no enumera files, no pagina, no modifica dades. Els sondejos INSERT estan restringits per la verificació de propietat de domini i opt-in explícit; mai s'executen contra objectius no verificats.

Cada troballa s'entrega amb l'URL exacta de la sol·licitud, l'estat de la resposta, la forma de la resposta (només capçalera) i el nom de la taula. El prompt de correcció amb IA al final de la troballa és un bloc SQL llest per copiar i enganxar que executes a l'editor SQL de Supabase.

Què fer quan l'escàner troba alguna cosa

Cada troballa de RLS és una emergència en temps d'execució. Els endpoints PostgREST públics són escanejats pels atacants en qüestió de minuts. La seqüència de remediació és mecànica:

  1. Audita cada taula. Executa SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'; a l'editor SQL de Supabase. Qualsevol fila amb rowsecurity = false és un problema.
  2. Habilita RLS a cada taula pública. Per defecte, aplica ENABLE ROW LEVEL SECURITY i FORCE ROW LEVEL SECURITY a cada taula creada — converteix-ho en una plantilla de migració.
  3. Escriu polítiques comanda a comanda. No facis servir FOR ALL USING (true). Escriu polítiques explícites per a SELECT, INSERT, UPDATE, DELETE — cadascuna delimitada a auth.uid() o a una columna d'org-id de auth.jwt().
  4. Verifica amb un segon compte. Registra't com a un usuari diferent, intenta llegir els registres d'un altre usuari directament a través de l'API REST. Si la resposta és 200, la política està trencada.
  5. Torna a escanejar. Després d'aplicar la correcció, torna a executar un escaneig de FixVibe contra el mateix URL. La troballa baas.supabase-rls hauria de desaparèixer.
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;

Com es compara això amb altres escàners

La majoria d'eines DAST genèriques (Burp Suite, OWASP ZAP, Nessus) no saben què és PostgREST. Rastrejaran la teva aplicació, ignoraran la ruta /rest/v1/ i informaran sobre les pàgines HTML que sí entenen. Snyk i Semgrep són eines d'anàlisi estàtica — troben fitxers de migració al teu repositori amb crides RLS mancants, però no poden demostrar que la base de dades desplegada estigui mal configurada. FixVibe omple aquest buit: passiu, conscient de BaaS, enfocat en el que un atacant no autenticat pot demostrar des de l'URL pública.

Preguntes freqüents

L'escàner llegirà o modificarà les meves dades?

No. Els escaneigs passius emeten com a màxim un SELECT ... limit=1 per taula descoberta per confirmar si RLS permet lectures anònimes. L'escàner registra la forma de la resposta, no el contingut de les files. Els sondejos INSERT, UPDATE i DELETE estan restringits per la verificació de propietat de domini i mai s'executen contra objectius no verificats.

Funciona això si el meu projecte de Supabase està pausat o en un domini personalitzat?

Els projectes pausats retornen 503 a cada sol·licitud — l'escàner informa que el projecte és inabastable. Els dominis personalitzats funcionen sempre que l'aplicació desplegada carregui el SDK client de Supabase al navegador; l'escàner extreu l'URL del projecte del bundle de tota manera.

Què passa si es rota la meva clau anon o canvia la meva clau publicable?

Torna a executar l'escaneig. L'escàner torna a extreure la clau del bundle actual a cada execució. La rotació només invalida l'informe anterior, no l'estat de les polítiques de la base de dades.

L'escàner comprova el nou model de clau publicable de Supabase (<code>sb_publishable_*</code>)?

Sí. El detector reconeix tant els JWT anon heretats com les claus més noves sb_publishable_* i les tracta de manera idèntica — totes dues són pensades per ser públiques i totes dues deixen RLS com a única línia de defensa.

Següents passos

Executa un escaneig gratuït de FixVibe contra el teu URL de producció — la comprovació baas.supabase-rls està habilitada a tots els plans, inclòs el gratuït. Per a una lectura més profunda sobre què més pot filtrar-se d'un projecte Supabase, consulta Clau de rol de servei de Supabase exposada a JavaScript i Llista de comprovació de seguretat de contenidors de Supabase Storage. Per a la vista general entre tots els proveïdors BaaS, llegeix Escàner de configuracions errònies de BaaS.

// escaneja la teva superfície de baas

Troba la taula oberta abans que ho faci una altra persona.

Introdueix un URL de producció. FixVibe enumera els proveïdors de BaaS amb què parla la teva aplicació, identifica els seus endpoints públics i informa del que un client no autenticat pot llegir o escriure. Gratis, sense instal·lació, sense targeta.

  • Pla gratuït — 3 escaneigs al mes, sense targeta al registre.
  • Identificació passiva de BaaS — no cal verificació de domini.
  • Supabase, Firebase, Clerk, Auth0, Appwrite i més.
  • Prompts de correcció amb IA a cada troballa — enganxa'ls a Cursor / Claude Code.
Escàner de RLS de Supabase: detecta taules amb seguretat a nivell de fila absent o trencada — Docs · FixVibe