El peligro del Bypass de RLS en Supabase: El error de seguridad Nº 1 en apps creadas con Lovable y Bolt.new
El error de seguridad más común en apps hechas con Lovable o Bolt.new: desactivar RLS en Supabase o usar la service_role key en frontend. Aprende a solucionarlo.
Compartir
Siguiente paso
Si esto te toca de cerca, mejor mirar tu stack real.
Abrimos Calendly aquí mismo, sin mandarte antes a otra página.
En este artículo
- ¿Qué es Row Level Security (RLS) y por qué es vital?
- Los 3 errores críticos que comete la IA al generar código con Supabase
- Error 1: Dejar RLS desactivado (Disabled)
- Error 2: Exponer la service_role key en el frontend
- Error 3: Crear políticas RLS "permisivas" (true para todo)
- Cómo testear la seguridad de tu app en 5 minutos
- Cómo solucionarlo y asegurar tu Supabase paso a paso
- 1. Activa RLS en todas tus tablas
- 2. Implementa políticas basadas en autenticación
- 3. Rota tus API Keys inmediatamente si expusiste la service_role
- ¿Estás seguro de que tu MVP está listo para recibir clientes reales?
- Referencias
Lo esencial
Este artículo está pensado para ayudarte a entender seguridad Supabase Lovable sin ruido, y decidir si te conviene corregirlo tú o revisarlo antes de salir a producción.
El desarrollo asistido por IA (o vibecoding) ha cambiado las reglas del juego. Herramientas como Lovable.dev, Bolt.new o Cursor permiten a cualquier persona levantar un MVP (Producto Mínimo Viable) completamente funcional en cuestión de horas.
Casi siempre, la base de datos por defecto elegida para estas aplicaciones es Supabase. Es rápida, fácil de integrar y ofrece autenticación lista para usar.
Sin embargo, en la carrera por construir rápido, las inteligencias artificiales suelen cometer un error de seguridad crítico: desactivar o puentear la seguridad por filas (Row Level Security - RLS) de Supabase, o peor aún, exponer la service_role key en el cliente.
Si tu app está configurada de esta manera, cualquier usuario con conocimientos básicos de desarrollo puede vaciar, modificar o borrar toda tu base de datos en menos de un minuto. En este artículo te explicamos cómo detectar este fallo en tu app y cómo solucionarlo antes de lanzar.
¿Qué es Row Level Security (RLS) y por qué es vital?
A diferencia de las bases de datos tradicionales que se ocultan detrás de un backend seguro (como una API en Node.js o Python), Supabase está pensada para ser consultada directamente desde el frontend del navegador.
Para evitar que un usuario consulte los datos de otro, Supabase utiliza Row Level Security (RLS) a nivel de base de datos en PostgreSQL.
RLS te permite definir reglas políticas (Policies) que le dicen a la base de datos: "El usuario A solo puede leer o escribir filas donde el campo user_id sea igual a su propio ID de usuario autenticado".
Si el RLS está desactivado, Supabase se comporta como una base de datos abierta al público. Cualquiera que tenga tu URL de Supabase y tu API key pública (que viaja de forma visible en el navegador de todos tus usuarios) tendrá acceso total de lectura y escritura.
Los 3 errores críticos que comete la IA al generar código con Supabase
Cuando le pides a una IA "conecta esto a Supabase y haz que funcione el CRUD de facturas", la IA prioriza que funcione a la primera. Para evitar errores de permisos complejos, suele tomar atajos peligrosos.
Error 1: Dejar RLS desactivado (Disabled)
Para que el frontend pueda guardar datos de inmediato sin configurar políticas, la IA a menudo crea las tablas con RLS desactivado.
❌ Lo que ocurre en tu base de datos:
En el panel de Supabase, verás una advertencia naranja que dice "RLS is disabled" en tu tabla. Si está desactivada, la base de datos acepta cualquier petición del cliente.
Cómo lo explota un atacante:
Cualquier usuario abre la consola del navegador (F12), copia tu supabaseUrl y tu supabaseAnonKey desde la pestaña Network, y ejecuta esto desde su propia consola:
// Un atacante puede leer los datos de TODOS tus clientes si RLS está desactivado
const { data, error } = await supabase
.from('facturas')
.select('*');
console.log(data); // Muestra absolutamente todo
Error 2: Exponer la service_role key en el frontend
Supabase tiene dos llaves principales:
anon: Diseñada para el frontend. Respeta las reglas de RLS.service_role: Diseñada únicamente para entornos de backend seguros. Esta llave ignora completamente el RLS y tiene privilegios de administrador absoluto.
Para evitar configurar políticas de RLS, a veces la IA te pide que pongas la service_role key en el archivo .env del frontend para que las llamadas funcionen.
❌ Código vulnerable (en tu cliente React/Vite/Next.js):
// NO HAGAS ESTO. NUNCA.
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabaseServiceKey = import.meta.env.VITE_SUPABASE_SERVICE_ROLE_KEY; // Exposición masiva
export const supabase = createClient(supabaseUrl, supabaseServiceKey);
Por qué pasa: La IA se frustró porque la política RLS bloqueaba una escritura y decidió usar la "llave maestra" para solucionar el error de forma rápida.
Consecuencia:
Cualquier persona que visite tu web puede extraer la service_role key de los archivos compilados de JavaScript y borrar todas tus tablas con un simple script.
Error 3: Crear políticas RLS "permisivas" (true para todo)
A veces la IA activa el RLS pero crea una política que anula su propósito por completo.
❌ Política generada por IA (PostgreSQL):
-- Esta política permite a CUALQUIERA leer y escribir en la tabla
CREATE POLICY "Permitir todo a usuarios anonimos"
ON public.facturas
FOR ALL
TO public
USING (true)
WITH CHECK (true);
Por qué pasa: La IA quiere que las operaciones de prueba funcionen sin necesidad de que el usuario esté logueado, y decide abrir la puerta de par en par. Esto es idéntico a tener RLS desactivado.
Cómo testear la seguridad de tu app en 5 minutos
Puedes hacer una auditoría rápida tú mismo usando la consola de Chrome o Firefox en tu propia web en producción:
- Ve a tu aplicación web.
- Abre las Herramientas de Desarrollador (
F12oCmd+Option+Ien Mac). - Ve a la pestaña Console (Consola).
- Copia y pega el siguiente código adaptado a una de tus tablas privadas (por ejemplo,
profilesoorders):
// Si usas el cliente global de supabase de tu app
const testLeak = async () => {
// Intentamos leer datos sin filtrar por nuestro usuario
const { data, error } = await window.supabaseClient // o el nombre que tenga tu cliente
.from('orders')
.select('*')
.limit(5);
if (data && data.length > 0) {
console.warn("⚠️ ALERTA DE SEGURIDAD: Los datos son accesibles públicamente.");
console.table(data);
} else {
console.log("✅ Acceso denegado o tabla vacía. RLS parece estar funcionando.");
}
};
testLeak();
Nota: Si tu cliente de Supabase no está expuesto en window, puedes buscar tu URL y Anon Key en las peticiones de red en la pestaña Network (filtrando por /rest/v1) y crear un cliente temporal en la consola.
Si el script te devuelve registros que pertenecen a otros usuarios, tienes una brecha de seguridad grave.
Cómo solucionarlo y asegurar tu Supabase paso a paso
1. Activa RLS en todas tus tablas
Lo primero es asegurarte de que ninguna tabla relevante quede abierta. Ejecuta esto en el SQL Editor de Supabase o actívalo desde el panel visual:
-- Activa RLS en la tabla facturas
ALTER TABLE public.facturas ENABLE ROW LEVEL SECURITY;
2. Implementa políticas basadas en autenticación
Una vez activado RLS, por defecto Supabase bloqueará todas las lecturas y escrituras. Debes crear políticas explícitas para permitir el acceso controlado.
✅ Política para permitir a un usuario ver solo sus propios registros:
CREATE POLICY "Los usuarios solo ven sus propias facturas"
ON public.facturas
FOR SELECT
TO authenticated
USING (auth.uid() = user_id);
✅ Política para permitir a un usuario insertar sus propios registros:
CREATE POLICY "Los usuarios solo insertan sus propias facturas"
ON public.facturas
FOR INSERT
TO authenticated
WITH CHECK (auth.uid() = user_id);
Nota: Asegúrate de que tu tabla tenga una columna user_id vinculada a la tabla auth.users de Supabase.
3. Rota tus API Keys inmediatamente si expusiste la service_role
Si en algún momento subiste la service_role key al frontend o la committeaste a GitHub (incluso si el repositorio es privado):
- Ve al panel de Supabase -> Settings -> API.
- Desplázate hasta la sección de llaves y haz clic en "Roll key" para invalidar la llave expuesta y generar una nueva.
- Actualiza tus variables de entorno en producción (por ejemplo, en Vercel, Railway o Netlify) pero solo en el backend.
¿Estás seguro de que tu MVP está listo para recibir clientes reales?
Construir con IA es increíblemente rápido, pero la IA no asume la responsabilidad si hackean tu base de datos o si expones información privada de tus usuarios (violando normativas como la GDPR).
Si no tienes conocimientos técnicos de bases de datos o ciberseguridad, lanzar tu app al mercado sin una revisión profesional es un riesgo enorme para tu negocio.
En Vibe2Prod nos especializamos precisamente en esto: revisamos el código y la infraestructura creados por tu IA, tapamos las brechas de seguridad (como RLS, SQL Injection o secretos expuestos) y realizamos un despliegue seguro a producción.
Ofrecemos opciones adaptadas a tus necesidades:
- Diagnóstico Exprés (390€): Revisión en videollamada de 1 hora para identificar vulnerabilidades críticas en tu base de datos y backend.
- Auditoría Preproducción (1.900€): Análisis a fondo de tu código, base de datos y auth con entrega de un informe completo y checklist de remediación.
- Hardening + Despliegue (4.500€): Auditoría completa, corrección directa del código vulnerable y despliegue profesional a producción supervisado.
y lanza tu aplicación con la tranquilidad de que tu base de datos está blindada.
Referencias
- Supabase. (2025). Row Level Security Guide. https://supabase.com/docs/guides/database/postgres/row-level-security
- OWASP. (2025). Top 10 API Security Risks. https://owasp.org/www-project-api-security/
- Vibe2Prod Internal Audit. (2026). Security flaws in AI-assisted Supabase implementations.
Si ya estás cerca del lanzamiento, mejor revisar el caso real.
Podemos mirar auth, configuración, secrets, datos y deploy antes de abrir producción. En 30 minutos te digo si necesitas diagnóstico, auditoría o hardening.
Seguir leyendo