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.