7 puntos de seguridad antes de lanzar tu app Lovable
Checklist de auditoría de seguridad para apps Lovable + Supabase: RLS, auth, roles y los gaps más frecuentes antes de pasar a producción ahora.
Resumen rápido
Lovable genera apps funcionales rápido, pero sus configuraciones por defecto dejan huecos de seguridad reales. Antes de lanzar a producción, necesitas revisar RLS en Supabase, validar roles y cerrar endpoints expuestos. Este checklist cubre los 7 puntos que más fallan.
TL;DR
Lovable genera apps funcionales rápido, pero sus configuraciones por defecto dejan huecos de seguridad reales. Antes de lanzar a producción, necesitas revisar RLS en Supabase, validar roles y cerrar endpoints expuestos. Este checklist cubre los 7 puntos que más fallan.
Por qué Lovable crea un falso sentido de seguridad
Lovable genera apps que funcionan. Login, dashboard, formularios, todo en minutos. El problema es que “funcionar” no es lo mismo que “ser segura”, y la brecha entre ambas cosas es exactamente donde los lanzamientos fallidos suceden.
La plataforma está optimizada para velocidad de prototipado. Eso significa que el código generado asume que tú, el fundador o PM, te encargarás de la capa de seguridad antes de abrir el producto a usuarios reales. Si no lo haces, estás lanzando una app donde cualquier usuario puede, en muchos casos, ver los registros de otros.
Este comportamiento no es un bug de Lovable: es una decisión de diseño que prioriza la velocidad de iteración sobre la seguridad de producción. El costo de esa decisión lo paga quien lanza sin revisar.
Este checklist cubre los 7 puntos que más frecuentemente quedan sin configurar. Cada uno corresponde a una categoría del OWASP Top 10 2025, el estándar de referencia para vulnerabilidades en aplicaciones web.
1. RLS desactivado en tus tablas de Supabase
Row Level Security es la primera línea de defensa. Cuando creas una tabla en Supabase desde Lovable, RLS no se activa automáticamente. Una tabla sin RLS permite que cualquier request autenticado, o incluso anónimo, lea o escriba todos sus registros.
El fix concreto: en el dashboard de Supabase, entra a Table Editor, selecciona cada tabla y activa “Enable RLS”. Luego crea políticas explícitas para cada operación: SELECT, INSERT, UPDATE, DELETE. Una política mínima para una tabla de usuarios se vería así: permitir SELECT solo cuando auth.uid() = user_id.
Si no defines ninguna política después de activar RLS, la tabla queda con acceso cero para todos, lo que también rompe tu app. Las políticas son obligatorias una vez que activas RLS.
Cómo verificar que RLS está activo correctamente
Una forma práctica de confirmar que tus políticas funcionan es usar el inspector de SQL de Supabase. Ejecuta una consulta como usuario anónimo y verifica que no retorna filas que no deberían ser visibles. También puedes revisar la pestaña “Policies” de cada tabla en el Table Editor: si aparece vacía con RLS activo, tienes un problema.
Una segunda verificación útil es revisar los logs de Supabase en tiempo real mientras navegas tu app como usuario de prueba. Cualquier query que retorne más filas de las esperadas indica una política mal configurada o ausente.
2. La service role key expuesta en el frontend
Supabase genera 2 claves: anon y service_role. La anon key es segura para el cliente porque respeta las políticas RLS. La service_role key bypasea todo, sin excepciones.
Lovable a veces incluye variables de entorno en el código frontend sin distinguir cuál es cuál. Antes de lanzar, busca en tu código cualquier referencia a SUPABASE_SERVICE_ROLE_KEY o service_role. Si aparece en archivos que corren en el navegador, la estás exponiendo a cualquiera que abra las DevTools.
La service role key va únicamente en funciones serverless o Edge Functions de Supabase, nunca en el bundle que descarga el usuario.
Qué hacer si ya la expusiste
Si encontraste la service role key en código que ya llegó al navegador o fue commiteado en un repositorio público, el primer paso es rotarla de inmediato desde Project Settings en Supabase. La clave anterior queda invalidada en segundos. Luego audita los logs de acceso para identificar si hubo requests inusuales en el período de exposición.
3. Rutas protegidas que no verifican el token
Lovable puede generar rutas con un componente de guard que revisa si hay una sesión activa en el cliente. El problema es que esa verificación ocurre en el frontend, y el frontend es código que cualquiera puede modificar.
La verificación real debe ocurrir en el servidor. En el contexto de Supabase, eso significa que tus Edge Functions y las políticas RLS deben validar el JWT de Supabase en cada request, no confiar en que el cliente ya verificó el estado de auth.
Revisa cada endpoint que retorna datos sensibles y confirma que hay una validación de auth.uid() del lado del servidor, no solo un redirect en el cliente.
Patrón recomendado para Edge Functions
Dentro de cada Edge Function que maneje datos sensibles, el primer bloque de código debe extraer el JWT del header Authorization, verificarlo con supabase.auth.getUser() y retornar un error 401 si la verificación falla. Solo después de esa verificación debe ejecutarse la lógica de negocio. Este patrón evita que un atacante eluda los guards del frontend y llame directamente a tus funciones con requests manipulados.
4. Roles sin granularidad: todos son “usuario”
La mayoría de apps generadas en Lovable tienen 2 estados: no autenticado y autenticado. Sin embargo, una app de producción suele necesitar al menos 3 roles: usuario final, administrador y, si aplica, superadmin o soporte interno.
Sin roles diferenciados, un usuario regular puede intentar acceder a rutas de admin simplemente conociendo la URL o manipulando una petición. La solución pasa por agregar un campo role en tu tabla de usuarios y construir políticas RLS que distingan: WHERE role = 'admin' para operaciones sensibles.
Supabase permite definir claims personalizados en el JWT usando una función de base de datos que se ejecuta antes de emitir el token. Esto es más seguro que leer el rol desde una tabla en cada request.
Cómo implementar roles con claims JWT en Supabase
El proceso tiene tres pasos. Primero, crea una función SQL en tu base de datos que retorne los claims adicionales para cada usuario, incluyendo el campo role. Segundo, registra esa función como hook en la configuración de Auth de Supabase bajo “Custom Access Token Hook”. Tercero, en tus políticas RLS y Edge Functions, lee el rol desde auth.jwt() -> 'role' en lugar de hacer una query adicional a la tabla de usuarios. Este enfoque reduce latencia y elimina una consulta extra por cada request autenticado.
Errores frecuentes al diseñar roles
Un error común es definir los roles en el frontend y confiar en que el backend los respeta sin verificación. Otro es crear roles en Supabase pero olvidar actualizar las políticas RLS para que los usen. Un tercer error es mezclar la lógica de roles con la lógica de negocio dentro de la app en lugar de delegarla completamente a las políticas de base de datos.
5. Emails de verificación y recuperación de contraseña sin configurar
Supabase Auth trae flujos de verificación de email y recuperación de contraseña, pero necesitan un proveedor SMTP configurado para funcionar en producción. Por defecto, usa el servidor de Supabase con límites muy bajos: 4 emails por hora en el plan gratuito.
Si lanzas sin configurar tu propio SMTP (Resend, SendGrid, Postmark), tus usuarios no recibirán emails de confirmación o, peor, los recibirán de un dominio genérico de Supabase que genera desconfianza y va a spam.
Configura el SMTP antes del lanzamiento. También personaliza las plantillas de email para que incluyan tu marca, no la de Supabase.
Qué proveedor SMTP elegir para apps en LatAm
Para proyectos en etapa temprana, Resend es la opción con mejor experiencia de configuración y tiene un plan gratuito generoso. SendGrid y Postmark son opciones maduras con mejor reputación de entrega para volúmenes altos. Los tres se integran en la sección “Auth, SMTP” del dashboard de Supabase en menos de 10 minutos. El criterio más importante no es el costo inicial sino la tasa de entrega en dominios de correo populares en LatAm como Hotmail y Gmail.
6. Storage de archivos sin políticas de acceso
Si tu app permite subir imágenes, documentos o cualquier archivo, Supabase Storage también requiere políticas explícitas. Un bucket creado sin políticas puede quedar en modo público, donde cualquiera con la URL descarga el archivo.
Crea políticas de storage que restrinjan el acceso según auth.uid(). Para archivos privados de usuario, la política debe verificar que el owner del objeto coincide con el usuario autenticado. Para archivos públicos intencionales, como fotos de perfil, puedes dejar el bucket en modo público pero con restricciones de escritura.
Lovable no genera estas políticas automáticamente al crear funcionalidad de carga de archivos.
Tipos de bucket y cuándo usar cada uno
Supabase Storage distingue entre buckets públicos y privados. Un bucket público sirve cualquier archivo sin autenticación, lo que es adecuado para assets estáticos como imágenes de marketing o logos. Un bucket privado requiere un token válido para cada descarga, lo que es necesario para documentos de usuario, facturas, contratos o cualquier archivo con datos personales. El error más frecuente es crear un bucket privado pero olvidar agregar las políticas de lectura, lo que resulta en que ni los propios usuarios pueden descargar sus archivos.
7. Variables de entorno en el repositorio de código
Si conectaste tu proyecto Lovable a GitHub, revisa que ningún archivo .env con credenciales reales haya quedado commiteado. Git tiene memoria larga: aunque borres el archivo después, el secreto queda en el historial y herramientas como git log o servicios de scanning automático lo detectan.
Agrega .env, .env.local y cualquier variante a tu .gitignore desde el primer commit. Para credenciales ya expuestas, rota las claves en Supabase de inmediato: ve a Project Settings, API, y genera nuevas claves. Las antiguas quedan invalidadas.
Los scanners automáticos de GitHub ya detectan patrones de Supabase keys y envían alertas, pero para cuando recibes la alerta el daño puede estar hecho.
Herramientas para detectar secretos expuestos
Además de los scanners de GitHub, puedes usar git-secrets o truffleHog de forma local antes de cada push para detectar patrones de credenciales en tu historial. Si usas GitHub Actions, puedes agregar un step que ejecute estos scanners en cada PR. Para proyectos que ya tienen historial comprometido, git filter-repo permite reescribir el historial eliminando el archivo sensible, aunque esto requiere forzar el push y coordinar con todos los colaboradores del repositorio.
Resumen: los 7 puntos en una sola tabla
| Punto | Riesgo si no se configura | Tiempo estimado de fix |
|---|---|---|
| RLS en tablas | Exposición de todos los datos | 30-60 minutos |
| Service role key | Acceso total a la base de datos | 15 minutos |
| Verificación de token en servidor | Bypass de autenticación | 1-2 horas |
| Roles granulares | Acceso no autorizado a admin | 2-4 horas |
| SMTP y emails | Flujos de auth rotos | 30 minutos |
| Políticas de Storage | Archivos privados públicos | 30-60 minutos |
| Variables de entorno | Credenciales expuestas | 15 minutos |
Conclusión
Ninguno de estos 7 puntos requiere código complejo ni semanas de trabajo. La mayoría se resuelven en el dashboard de Supabase en una tarde. Lo que sí requieren es revisión deliberada antes de darle acceso a usuarios reales, porque Lovable no lo hace por ti.
El costo de ignorar esta lista no es solo técnico. Una brecha de datos en una app que maneja información de clientes puede generar pérdida de confianza, problemas legales bajo marcos como la Ley de Protección de Datos Personales en varios países de LatAm, y costos de remediación mucho más altos que los que implicaría haber configurado correctamente desde el inicio.
Usa este checklist como la última verificación antes de apuntar tu dominio a producción. Si ya lanzaste sin revisar estos puntos, úsalo como punto de partida para una auditoría de emergencia.
¿Necesitas ayuda para construir esto?
Kreante acompaña a PyMEs y founders en LatAm que quieren reemplazar SaaS caro con IA personalizada. Hemos shipped 265+ proyectos (60% LowCode/AI, 70% B2B) en US, Europa y LatAm.
Preguntas frecuentes
- ¿Lovable tiene autenticación incluida?
- Lovable puede generar código de auth usando Supabase Auth, pero no la activa ni la configura por defecto. Tú debes habilitarla, configurar los roles y proteger cada tabla con RLS.
- ¿Qué es RLS en Supabase y por qué importa?
- Row Level Security (RLS) es el mecanismo de Supabase que controla qué filas puede leer o escribir cada usuario. Sin RLS activo, cualquier usuario autenticado, o incluso anónimo, puede acceder a todos los datos de una tabla.
- ¿Puedo lanzar una app Lovable a producción sin configurar seguridad?
- Técnicamente sí, pero es un riesgo grave. Si tu app maneja datos de usuarios, pagos o información sensible, un atacante puede leer o modificar registros de otros usuarios sin mayor esfuerzo.
- ¿Qué diferencia hay entre anon key y service role key en Supabase?
- La anon key es para el cliente: tiene permisos limitados por RLS. La service role key bypasea todo RLS y no debe aparecer nunca en el frontend ni en código expuesto al navegador.
- ¿Lovable genera código con vulnerabilidades por defecto?
- No es que genere código malicioso, sino que prioriza funcionalidad sobre seguridad. El código resultante tiende a omitir políticas RLS, validaciones del lado del servidor y manejo correcto de roles, que son responsabilidad del equipo que lanza la app.
Referencias
- Artículo Supabase Docs: Row Level Security
- Artículo Supabase Docs: Auth y roles
- Artículo Lovable Docs: Conectar Supabase
- Artículo OWASP Top 10 2025
IA, low-code y automatización para equipos en LatAm y España.
Ver artículos →Si quieres implementar esto en tu empresa, Kreante construye sistemas de low-code e IA para equipos en LatAm y España. Ofrecen una auditoría gratuita para proyectos cualificados.