pentest-101indiepre-launch

Supabase Security Checklist 2026: 15 Checks Esenciales para Producción

La lista de seguridad para Supabase en prod: RLS, service_role key, storage y los 15 errores más comunes. Sable los detecta en un scan pre-launch.

Diego Diaz
10 min

Por qué este checklist existe

En cada pentest que SableOffensive realiza sobre stacks con Supabase, encontramos los mismos 5-6 errores repetidos. No son bugs del producto — son misconfigurations que ocurren porque Supabase prioriza developer experience y deja decisiones críticas de seguridad al desarrollador.

Este checklist es el resultado de auditar más de 30 startups que usan Supabase. Si seguís estos 15 puntos, evitás el 95% de las vulnerabilidades comunes.

1. Habilita Row Level Security (RLS) en TODAS las tablas

Esta es la #1 vulnerabilidad que encontramos. Supabase expone PostgreSQL directamente al cliente vía la anon key. Sin RLS habilitado, cualquier visitante puede leer toda tu tabla con una request HTTP.

-- Verifica qué tablas NO tienen RLS
SELECT schemaname, tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public' AND rowsecurity = false;

-- Habilita RLS en una tabla
ALTER TABLE public.profiles ENABLE ROW LEVEL SECURITY;

Importante: Habilitar RLS sin políticas hace que la tabla quede inaccesible. Definí siempre políticas explícitas.

2. Define políticas RLS específicas (no "USING (true)")

El segundo error más común: habilitar RLS pero usar USING (true), que es equivalente a no tener RLS.

-- MAL: cualquiera puede ver todo
CREATE POLICY "Anyone can read" ON profiles
  FOR SELECT USING (true);

-- BIEN: solo el dueño puede ver su perfil
CREATE POLICY "Users see own profile" ON profiles
  FOR SELECT USING (auth.uid() = user_id);

Define políticas por separado para SELECT, INSERT, UPDATE, DELETE. No uses FOR ALL sin pensarlo.

3. NUNCA expongas el service_role key en el cliente

El service_role key bypassea RLS. Si está en el bundle del cliente, cualquiera tiene acceso completo a tu base de datos. Solo debe usarse en:

  • Edge Functions de Supabase
  • Backends propios (Express, FastAPI, etc.)
  • Scripts de migración o admin (nunca commiteados)

Para verificar que no está expuesto:

# Buscar en el bundle del cliente
npm run build
grep -r "service_role" dist/ build/ .next/static/

4. Restringe la anon key con RLS, no con código cliente

La anon key SE va a estar en el cliente — eso es esperado. Lo que no debe pasar es que la anon key dé acceso a más de lo que un visitante anónimo debería ver. Tus políticas RLS deben asumir que el atacante usa la anon key directamente desde curl.

5. Habilita confirmación de email obligatoria

Sin email confirmation, cualquiera puede crear cuentas con emails que no le pertenecen. Esto permite ataques de account takeover y spam.

En Authentication → Settings → User Signups: activá "Enable email confirmations".

6. Configura políticas de password

Por defecto, Supabase acepta contraseñas de 6 caracteres. Para producción:

  • Mínimo 10 caracteres
  • Combinación de letras, números, símbolos
  • Habilitar "Leaked Password Protection" (chequea contraseñas contra HaveIBeenPwned)

7. Habilita rate limiting en endpoints de auth

Sin rate limiting, un atacante puede:

  • Brute-force contraseñas
  • Enumerar emails registrados
  • Spammear el endpoint de signup

Supabase incluye rate limiting básico, pero para producción reforzalo con Cloudflare WAF, Upstash, o middleware en Next.js.

8. Audita los policies de tus Storage Buckets

Storage en Supabase usa políticas similares a las tablas. Errores comunes:

  • Bucket público sin querer: archivos privados accesibles sin auth.
  • Política de upload sin validación de tamaño: permite DoS subiendo archivos enormes.
  • Sin restricción de MIME type: permite upload de ejecutables o scripts.
-- Solo el dueño puede ver sus archivos
CREATE POLICY "User access own files" ON storage.objects
  FOR SELECT USING (auth.uid()::text = (storage.foldername(name))[1]);

9. Limita los datos en JWT custom claims

Si agregás campos custom al JWT (via app_metadata), nunca incluyas:

  • PII completa (nombre, email, teléfono)
  • Tokens de servicios externos
  • Roles administrativos sin verificación adicional en el servidor

El JWT es base64, no encriptado. Cualquiera con el token lo puede leer.

10. Audita las Edge Functions por secretos hardcodeados

Las Edge Functions corren en Deno. Errores comunes:

  • Service keys hardcodeados en el código (en lugar de Deno.env.get())
  • Falta de validación de entrada en parámetros HTTP
  • CORS demasiado permisivo (Access-Control-Allow-Origin: *)
  • Sin verificación de autenticación en funciones que usan service_role

11. Implementa MFA para usuarios admin

Supabase soporta TOTP-based MFA. Para cuentas de admin o de owner del proyecto:

  • Habilitá MFA obligatorio en el dashboard de Supabase.
  • Para usuarios finales con privilegios elevados, implementá MFA en tu app vía supabase.auth.mfa.

12. Restringe el acceso al dashboard por IP

Si tu equipo siempre se conecta desde IPs conocidas (oficina, VPN), agregá IP allowlisting al dashboard de Supabase. Esto previene compromiso por phishing de credenciales del owner.

13. Auditá las relaciones (Foreign Keys) y cascadas

Las cascadas ON DELETE CASCADE mal configuradas permiten ataques de eliminación masiva. Si un atacante puede borrar su cuenta, ¿qué tablas relacionadas se borran también? ¿Pueden eliminarse datos de otros usuarios?

14. Habilita Logging y Audit Trail

Supabase Pro+ incluye logs detallados. Para producción:

  • Activá Database Webhooks para tracking de cambios en tablas críticas.
  • Considerá agregar tablas de audit (audit_log) con triggers en tablas de usuarios y permisos.
  • Conectá los logs a Datadog, Logtail, o Better Stack para alertas.

15. Define backups y disaster recovery

Supabase Pro hace daily backups automáticos por 7 días. Para producción seria:

  • Habilitá Point-in-Time Recovery (PITR) en planes Team+.
  • Hacé backups manuales antes de migraciones o cambios mayores.
  • Probá tu plan de restauración al menos una vez por trimestre. Un backup que nunca probaste es un backup que no funciona.

Verifica todo con un Pentest

Esta checklist es un piso, no un techo. Las vulnerabilidades reales aparecen en la combinación de cosas: una política RLS que parece correcta + un endpoint que la bypasea + una storage policy demasiado permisiva = filtración de datos.

Si tu app está en Supabase y querés validar que tu configuración es segura:

  • Free: probá nuestro scan gratuito de headers para validar la base.
  • Pre-Launch Check ($29): cubre la base de seguridad incluyendo verificación de service_role key expuesto.
  • Founder Shield ($79): incluye auditoría completa de RLS, storage policies, y Edge Functions.
  • Scale Secure ($199): auditoría profunda + revisión de código de tus políticas + monitoreo continuo.

SableOffensive ha auditado más de 30 startups en Supabase. Conocemos los patrones, los errores comunes, y los attack vectors específicos del stack. Empezá con un scan o escribí a [email protected] con preguntas.