Para añadir Row Level Security a tu app en Lovable, activa RLS en cada tabla de tu proyecto Supabase y escribe políticas que limiten a cada usuario a sus propias filas. Es imprescindible porque Supabase crea las tablas con RLS desactivado, así que sin este paso cualquiera con tu clave anon pública puede consultar y volcar toda la base de datos, exactamente el fallo detrás de CVE-2025-48757. Puedes hacerlo desde el panel de Supabase o pidiéndoselo a la IA de Lovable, y luego debes verificarlo consultando con la clave anon.
Respuesta rápida
Añadir RLS son dos pasos: activarlo en cada tabla y escribir políticas. Según la documentación de Supabase, las tablas se crean con RLS desactivado, así que hay que activarlo en todas. Luego escribe una política por operación, para leer, crear, editar y borrar, que use auth.uid() para que cada usuario acceda solo a sus filas. La clave anon es pública por diseño, según la documentación de claves, y es segura solo cuando RLS la gobierna. Sin RLS, un atacante la usa para volcar tus tablas, el fallo de CVE-2025-48757. Verifica consultando con la clave anon sin sesión.
Por qué tu app de Lovable necesita RLS
Row Level Security es la capa que hace segura una app de Supabase, y es justo la que las herramientas de IA suelen omitir. Supabase crea las tablas con RLS desactivado por defecto, de modo que si tu proyecto de Lovable nunca lo activa, la clave anon pública, que viaja en el cliente, puede consultar cualquier tabla y descargarla entera: listas de usuarios, registros de pago u otros datos sensibles, sin iniciar sesión.
Esto no es teórico. En CVE-2025-48757, un investigador encontró 170 proyectos de Lovable cuyas tablas eran legibles por peticiones no autenticadas usando solo la clave anon, porque faltaba RLS. La clave anon no se había filtrado, es pública a propósito; el problema era que nada protegía los datos detrás de ella. Añadir RLS es lo que cierra esa puerta.
Paso 1: activa RLS en cada tabla
El primer paso es activar Row Level Security en todas las tablas, sin excepción. En el panel de Supabase, abre el editor de tablas, selecciona cada tabla y activa RLS; también puedes hacerlo con SQL mediante ALTER TABLE nombre_tabla ENABLE ROW LEVEL SECURITY. Una tabla sin RLS queda completamente abierta a la clave anon, así que ninguna puede quedarse fuera.
Ten en cuenta un efecto importante: al activar RLS sin ninguna política, la tabla queda cerrada por completo, es decir, nadie puede leer ni escribir hasta que crees políticas. Eso es lo correcto por defecto, y el siguiente paso es abrir el acceso justo a lo necesario mediante políticas, en lugar de dejar la tabla abierta a todo el mundo.
Paso 2: escribe políticas para cada operación
Con RLS activo, defines qué puede hacer cada usuario mediante políticas, y conviene una por operación. En Postgres, las operaciones son SELECT para leer, INSERT para crear, UPDATE para editar y DELETE para borrar, y cada una puede tener su propia política. La tabla siguiente resume el patrón habitual.
| Operación | Política típica | Con qué se comprueba |
|---|---|---|
| SELECT (leer) | El usuario lee solo sus filas | auth.uid() = user_id |
| INSERT (crear) | El usuario crea filas como suyas | auth.uid() = user_id (WITH CHECK) |
| UPDATE (editar) | El usuario edita solo sus filas | auth.uid() = user_id (USING y WITH CHECK) |
| DELETE (borrar) | El usuario borra solo sus filas | auth.uid() = user_id (USING) |
La idea es abrir solo lo que cada usuario necesita. En lugar de una regla que permita todo, escribes reglas concretas que comparan la identidad del usuario con la fila, de modo que cada persona accede únicamente a lo suyo. Sin una política para una operación, esa operación queda denegada, que es el comportamiento seguro.
La política más común: cada usuario ve solo sus filas
La política que necesita casi cualquier app es sencilla: cada usuario accede solo a las filas que le pertenecen. Para lograrlo, tus tablas deben tener una columna que identifique al propietario, por ejemplo user_id, y la política compara esa columna con la identidad del usuario autenticado, disponible en Supabase como auth.uid().
Una política de lectura típica permite SELECT cuando auth.uid() coincide con el user_id de la fila. Repites la idea para crear, editar y borrar, usando USING para lo que el usuario puede ver o afectar y WITH CHECK para lo que puede escribir. Con estas cuatro políticas, un usuario no puede leer ni tocar los datos de otro, aunque comparta la misma clave anon pública.
Hacerlo en Lovable o en el panel de Supabase
Tienes dos caminos, y ambos funcionan porque Lovable se conecta a un proyecto real de Supabase. Puedes pedirle a la IA de Lovable que active RLS y escriba las políticas, describiendo qué debe poder hacer cada usuario; o puedes ir directamente al panel de Supabase y configurarlo tú, con el editor de políticas o con SQL.
Cualquiera que sea el camino, la responsabilidad de verificar es tuya. La IA puede generar políticas incompletas o dejar una tabla sin cubrir, así que después de pedírselo revisa en el panel de Supabase que RLS está activo en todas las tablas y que cada operación tiene su política. No des por hecho que "hecho por la IA" significa "hecho bien".
Un detalle de rendimiento: (select auth.uid())
Al escribir políticas hay un detalle que mejora el rendimiento. Llamar a auth.uid() directamente en una política hace que Postgres la evalúe fila por fila, lo que en tablas grandes ralentiza las consultas. Envolver la llamada como (select auth.uid()) permite a Postgres evaluarla una sola vez, lo que puede acelerar mucho las consultas sin cambiar la seguridad.
Es un ajuste pequeño con un impacto real en tablas con muchas filas. La lógica de seguridad es idéntica, cada usuario sigue viendo solo lo suyo, pero la consulta es más eficiente. Si tu app crece, adoptar esta forma desde el principio te evita revisar todas las políticas más adelante.
Verifica que RLS funciona
Activar RLS y escribir políticas no basta; hay que comprobar que de verdad protege. La tabla siguiente da una lista di verifica clara.
| Paso | Acción | Confirma |
|---|---|---|
| 1 | Activa RLS en cada tabla | Ninguna tabla queda abierta |
| 2 | Crea políticas para SELECT, INSERT, UPDATE, DELETE | Cada operación está cubierta |
| 3 | Usa auth.uid() para limitar por usuario | Cada uno ve solo lo suyo |
| 4 | Consulta con la clave anon sin sesión | No devuelve datos ajenos |
| 5 | Prueba con dos usuarios distintos | El aislamiento funciona |
| 6 | Revisa que no haya service_role en el cliente | Nada omite RLS |
La comprobación más importante es la cuarta: consulta tus tablas con la clave anon pública, sin sesión iniciada, y confirma que no devuelve datos que no debería. Es exactamente la prueba que hace un atacante o un bot de rastreo, así que superarla tú mismo es la señal directa de que el fallo de CVE-2025-48757 no está en tu app.
Errores comunes al añadir RLS
Los errores al añadir RLS se repiten. El más grave es dejar una tabla sin activar RLS, que queda abierta aunque las demás estén protegidas. Otro es activar RLS pero olvidar una operación, por ejemplo cubrir la lectura y no la escritura. Y otro es escribir una política demasiado permisiva, del tipo "permitir a todos", que en la práctica anula la protección.
Evitarlos es cuestión de método. Recorre todas las tablas, confirma que cada una tiene RLS activo y una política para cada operación que uses, y prueba con dos usuarios distintos para ver que el aislamiento funciona. Y nunca dejes la clave service_role en el cliente, porque omite RLS por completo y haría inútil todo el trabajo anterior.
Antes de publicar, escanea la build
RLS protege tu backend, pero tu app publicada también puede arrastrar problemas del lado del cliente que RLS no cubre: una clave incrustada, tráfico en claro o una configuración insegura. Como las herramientas de IA facilitan estos descuidos, revisar la build antes de publicar los detecta cuando aún son baratos de corregir.
Un escáner como PTKD.com analiza tu .apk o .ipa y devuelve resultados ordenados por gravedad y alineados con OWASP MASVS, incluidos los secretos embebidos y las configuraciones de red inseguras. Con un límite claro: un escáner de la build revisa la app que publicas, no tu panel de Supabase, así que no sustituye a activar RLS ni a escribir políticas. Detecta la exposición del lado del cliente; el backend lo aseguras tú con RLS.
Qué recordar
- Supabase crea las tablas con RLS desactivado, así que actívalo en todas las tablas de tu app de Lovable.
- Escribe una política por operación, para leer, crear, editar y borrar, usando auth.uid() para limitar a cada usuario a sus filas.
- Puedes hacerlo en Lovable o en el panel de Supabase, pero verifica tú mismo el resultado.
- Comprueba consultando con la clave anon sin sesión que no expone datos ajenos, el fallo de CVE-2025-48757.
- Antes de publicar, escanea la build con PTKD.com para los problemas del lado del cliente que RLS no cubre.




