FixVibe

// docs / baas security / supabase rls scanner

Escáner de RLS de Supabase: atopa táboas con seguranza a nivel de fila ausente ou rota

A seguranza a nivel de fila (RLS) é o único que se interpón entre os datos dos teus clientes e internet cando publicas unha aplicación apoiada en Supabase. As ferramentas de codificación con IA xeran código con forma de RLS que compila, publícase e filtra datos silenciosamente — táboas creadas sen RLS habilitado, políticas que len pero nunca restrinxen, predicados que comparan unha columna consigo mesma. Este artigo amosa que pode probar un escáner de RLS de Supabase desde o exterior, as catro formas de RLS rota que aparecen en aplicacións xeradas por IA e como escanear o teu propio despregamento en menos dun minuto.

Que pode probar un escaneo RLS externo

Un escaneo RLS pasivo execútase contra o endpoint PostgREST que Supabase expón en https://[project].supabase.co/rest/v1/. Só usa a clave publicábel anon — a mesma que utiliza o teu navegador — e sondea os metadatos de listaxe de táboas, as lecturas anónimas e as escrituras anónimas. Nunca se autentica como usuario e nunca toca os privilexios de rol de servizo. Calquera cousa que poida facer, un atacante non autenticado en internet tamén pode facela.

Desde fóra da base de datos, un escáner pode confirmar o seguinte con alta confianza:

  • RLS está desactivado nunha táboa. PostgREST devolve filas para un SELECT anónimo cando RLS está desactivado ou cando unha política o permite. Calquera dos dous casos é un achado.
  • O rol anónimo pode listar táboas. Un GET /rest/v1/ coa clave anon devolve o esquema OpenAPI de cada táboa sobre a que o rol anon teña calquera privilexio. As aplicacións xeradas por IA concédenlles con frecuencia USAGE sobre o esquema e SELECT sobre cada táboa, o que expón o mapa completo do esquema mesmo cando RLS nega as lecturas reais.
  • O rol anónimo pode inserir. Un POST de sondaxe cunha conxectura sobre a forma das columnas terá éxito se RLS non ten unha política INSERT que o negue — mesmo se SELECT está bloqueado.
  • A clave de rol de servizo está no bundle do navegador. Adxacente a RLS: se un escáner atopa SUPABASE_SERVICE_ROLE_KEY ou calquera JWT con role: service_role no bundle de JavaScript, RLS é irrelevante — quen posúa esa clave evita calquera política.

Que non pode probar un escaneo externo

Sé honesto sobre os límites do escáner. Un escaneo RLS externo non pode ler a túa táboa pg_policies, os teus ficheiros de migración nin o predicado exacto de ningunha política. Infire a partir do comportamento de caixa negra, o que significa que ás veces informará dun achado que resulta ser datos públicos intencionais (unha táboa de boletín de marketing, un catálogo público de produtos). O informe de FixVibe márcaos como confianza media cando o escáner non pode desambiguar a intención — revisa o nome da táboa e decide.

As catro formas de RLS rota que producen as ferramentas de IA

Cando apuntas Cursor, Claude Code, Lovable ou Bolt cara a Supabase, aparecen os mesmos catro patróns de RLS rota en miles de aplicacións. Cada un deles pasa a comprobación de tipos, compila e publícase:

Forma 1: RLS nunca activado

O modo de fallo máis común. A migración crea a táboa pero o desenvolvedor (ou a ferramenta de IA) esquece ALTER TABLE ... ENABLE ROW LEVEL SECURITY. PostgREST serve gustosamente toda a táboa a calquera con a clave anon. Solución: ALTER TABLE public.[name] ENABLE ROW LEVEL SECURITY; ALTER TABLE public.[name] FORCE ROW LEVEL SECURITY;. FORCE non é opcional — sen el, o propietario da táboa (e calquera rol con propiedade da táboa) salta RLS.

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

Forma 2: RLS activado, sen políticas

Un fallo máis sutil. RLS está activado pero non se escribiron políticas. O comportamento por defecto en PostgreSQL é denegar, así que os usuarios autenticados non ven nada — e o desenvolvedor engade USING (true) para que a aplicación funcione, o que permite que todos lean todo. Solución: escribe unha política con ámbito por auth.uid(): CREATE POLICY "select_own" ON public.[name] FOR SELECT USING (auth.uid() = user_id); e unha política INSERT/UPDATE/DELETE equivalente.

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

Forma 3: A política compara a columna consigo mesma

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 en SELECT pero non en INSERT/UPDATE

O desenvolvedor bloquea as lecturas pero esquece as escrituras. As políticas de RLS son por comando. FOR SELECT protexe só as lecturas; un cliente anónimo aínda pode INSERT se ningunha política o nega. Solución: escribe unha política por comando, ou usa FOR ALL con cláusulas USING e WITH CHECK explícitas.

Como funciona o escáner de RLS de Supabase de FixVibe

A comprobación baas.supabase-rls execútase en tres etapas, cada unha con niveis de confianza explícitos:

  1. Etapa 1 — identificación. O escáner rastrexa a aplicación despregada, analiza o seu bundle de JavaScript e extrae o URL do proxecto Supabase e a clave anon da configuración en tempo de execución. Sen adiviñar DNS, sen forza bruta — le o que le o navegador.
  2. Etapa 2 — descubrimento do esquema. Un único GET /rest/v1/ coa clave anon devolve o esquema OpenAPI de cada táboa que o rol anon pode ver. O escáner rexistra os nomes das táboas pero non le datos de fila nesta etapa.
  3. Etapa 3 — sondaxes de lectura e escritura. Para cada táboa descuberta, o escáner emite un SELECT anónimo con limit=1. Se devolve filas, RLS é permisivo. O escáner detense aí — non enumera filas, non pagina, non modifica datos. As sondaxes INSERT requiren propiedade de dominio verificada e participación explícita; nunca se executan contra obxectivos non verificados.

Cada achado vén co URL exacto da solicitude, o status da resposta, a forma da resposta (só cabeceira) e o nome da táboa. O prompt de corrección con IA no fondo do achado é un bloque SQL para copiar e pegar que executas no editor SQL de Supabase.

Que facer cando o escáner atopa algo

Cada achado de RLS é unha emerxencia en tempo de execución. Os endpoints PostgREST públicos son escaneados por atacantes en minutos. A secuencia de remediación é mecánica:

  1. Audita cada táboa. Executa SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public'; no editor SQL de Supabase. Calquera fila con rowsecurity = false é un problema.
  2. Activa RLS en cada táboa pública. Por defecto, ENABLE ROW LEVEL SECURITY e FORCE ROW LEVEL SECURITY en cada táboa creada — faino unha plantilla de migración.
  3. Escribe políticas comando a comando. Non uses FOR ALL USING (true). Escribe políticas explícitas para SELECT, INSERT, UPDATE, DELETE — cada unha con ámbito a auth.uid() ou a unha columna org-id de auth.jwt().
  4. Verifica cunha segunda conta. Rexístrate como un usuario diferente, intenta ler rexistros doutro usuario directamente vía a API REST. Se a resposta é 200, a política está rota.
  5. Reescanea. Despois de aplicar a corrección, volve executar un escaneo de FixVibe contra o mesmo URL. O achado baas.supabase-rls debería desaparecer.
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;

Como se compara isto con outros escáneres

A maioría das ferramentas xenéricas de DAST (Burp Suite, OWASP ZAP, Nessus) non saben o que é PostgREST. Rastrexarán a túa aplicación, ignorarán a ruta /rest/v1/ e informarán das páxinas HTML que si entenden. Snyk e Semgrep son ferramentas de análise estática — atopan ficheiros de migración no teu repositorio con chamadas RLS ausentes, pero non poden probar que a base de datos despregada estea mal configurada. FixVibe sitúase no oco: pasivo, consciente de BaaS, centrado no que un atacante non autenticado pode probar desde o URL público.

Preguntas frecuentes

O escáner lerá ou modificará os meus datos?

Non. Os escaneos pasivos emiten como moito un SELECT ... limit=1 por táboa descuberta para confirmar se RLS permite lecturas anónimas. O escáner rexistra a forma da resposta, non os contidos da fila. As sondaxes INSERT, UPDATE e DELETE requiren propiedade de dominio verificada e nunca se executan contra obxectivos non verificados.

Isto funciona se o meu proxecto Supabase está pausado ou nun dominio personalizado?

Os proxectos pausados devolven 503 en cada solicitude — o escáner informa de que o proxecto é inalcanzable. Os dominios personalizados funcionan sempre que a aplicación despregada aínda cargue o SDK cliente de Supabase no navegador; o escáner extrae o URL do proxecto do bundle en calquera caso.

Que pasa se a miña clave anon se rota ou cambia a miña clave publicábel?

Reexecuta o escaneo. O escáner volve extraer a clave do bundle actual en cada execución. A rotación invalida só o informe anterior, non o estado de política da base de datos.

O escáner comproba o novo modelo de clave publicábel de Supabase (<code>sb_publishable_*</code>)?

Si. O detector recoñece tanto os JWT anon herdados como as novas claves sb_publishable_* e trátaos de forma idéntica — ambas están pensadas para ser públicas e ambas deixan RLS como única liña de defensa.

Próximos pasos

Executa un escaneo gratuíto de FixVibe contra o teu URL de produción — a comprobación baas.supabase-rls está habilitada en todos os plans, incluído o plan gratuíto. Para unha lectura máis profunda sobre o que máis pode filtrarse dun proxecto Supabase, mira Clave de rol de servizo de Supabase exposta en JavaScript e Lista de comprobación de seguranza de buckets de almacenamento de Supabase. Para a visión global de todos os provedores BaaS, le Escáner de configuración incorrecta de BaaS.

// escanea a túa superficie baas

Atopa a táboa aberta antes de que outra persoa o faga.

Introduce un URL de produción. FixVibe enumera os provedores de BaaS cos que fala a túa aplicación, identifica os seus endpoints públicos e informa do que un cliente non autenticado pode ler ou escribir. Gratis, sen instalación, sen tarxeta.

  • Plan gratuíto — 3 escaneos ao mes, sen tarxeta de rexistro.
  • Identificación pasiva de BaaS — non se require verificación de dominio.
  • Supabase, Firebase, Clerk, Auth0, Appwrite e máis.
  • Prompts de corrección con IA en cada achado — pégaos de volta en Cursor / Claude Code.
Escáner de RLS de Supabase: atopa táboas con seguranza a nivel de fila ausente ou rota — Docs · FixVibe