← Guías por stack

Lovable

Seguridad y visibilidad para tu app de Lovable

Lovable te deja lanzar una app preciosa en minutos, pero a menudo como una SPA que la IA no ve y con claves que se cuelan en el frontend. Escanea tu web y descubre qué falta antes de compartirla.

Riesgos típicos en Lovable

Invisible para la IA

Si tu contenido solo aparece tras ejecutar JavaScript, los crawlers de IA ven una página en blanco y no pueden citarte. Es el fallo AEO más común en apps generadas.

Claves de API en el navegador

Al conectar servicios, la IA suele meter la clave directamente en el frontend, donde queda visible para cualquiera. Deben vivir en el servidor.

Cabeceras y SEO básico ausentes

Las apps generadas suelen salir sin cabeceras de seguridad ni meta etiquetas de SEO. Son arreglos rápidos que marcan una gran diferencia.

"Seguridad en Lovable" son dos cosas que conviene separar. La primera es el proyecto de Lovable en sí: qué pegas en el chat, dónde guarda los secretos, quién puede ver tu proyecto y dónde acaba desplegada la app. La segunda es el código que Lovable genera, que es una SPA con React y Supabase y trae siempre los mismos cinco o seis fallos. Esta guía cubre las dos, con un bloque de instrucciones para la sección Knowledge de tu proyecto, un prompt de revisión antes de publicar y la forma de comprobar el resultado desde fuera.

Parte 1: proteger tu proyecto de Lovable

Lo que pegas en el chat se queda

El chat del proyecto es el historial de tu app: cada prompt, cada clave que pegaste "para que funcione" y cada respuesta. Si una clave secreta entra por el chat, el modelo tiende a escribirla directamente en el código del frontend, y a partir de ahí viaja en el bundle a todos los visitantes. La regla es simple: las claves nunca entran por el chat. Cuando Lovable te pide un secreto para conectar un servicio, usa el cuadro de secretos que te ofrece; eso lo guarda como variable de las Edge Functions de Supabase, del lado del servidor, y el código generado lo lee con Deno.env.get.

Secretos: servidor sí, navegador no

Lovable sabe hacer dos cosas con una integración: llamarla desde el navegador o desde una Edge Function. La primera es correcta para claves públicas (la anon de Supabase, la publishable de Stripe, el ID de un proyecto). La segunda es la única opción para claves secretas (OpenAI, Resend, la secret de Stripe, la service_role). Si al pedir una función el resultado la llama desde un componente de React con la clave dentro, pídele explícitamente que la mueva a una Edge Function. Más en secretos que tu app filtra en el navegador.

Visibilidad del proyecto y del código

Un proyecto público en Lovable expone el código y el historial de prompts a cualquiera que tenga el enlace, incluida cualquier clave que alguna vez pegaste. Revisa la visibilidad en los ajustes del proyecto y, si has activado la sincronización con GitHub, que el repositorio sea privado. Si una clave estuvo en un proyecto o repositorio público, dala por comprometida y rótala.

Dónde vive la app publicada

Lovable publica en un subdominio .lovable.app o en tu dominio propio. Ese hosting no te deja configurar cabeceras de seguridad ni redirecciones personalizadas. Para muchas apps es suficiente; si necesitas Content-Security-Policy, HSTS o reglas de caché, exporta a GitHub y despliega en Vercel o Netlify con su archivo de configuración. Ten en cuenta también que la URL de preview de cada versión es accesible para quien la tenga.

Supabase es tuyo, no de Lovable

Al conectar Supabase (o al usar el backend gestionado de Lovable, que es Supabase por debajo), Lovable crea tablas, políticas y funciones por ti. Pero RLS, buckets y ajustes de Auth siguen siendo responsabilidad tuya. Lovable añadió una revisión de seguridad antes de publicar tras la CVE-2025-48757; tómala como un primer filtro, no como garantía, y repasa la guía de seguridad para Supabase, que tiene tres consultas SQL para auditar el proyecto en un minuto.

Parte 2: los fallos que Lovable mete en tu código

  • Tablas sin RLS o con políticas using (true). El origen de la CVE y el fallo más grave. Cualquiera con la clave anon lee y escribe tus datos.
  • Comprobaciones de permisos solo en el frontend. Una ruta /admin que solo esconde el botón si el usuario no es administrador. El servidor (RLS o la Edge Function) tiene que comprobarlo también, porque la API se puede llamar sin pasar por la interfaz.
  • Edge Functions sin autenticación ni límite. La plantilla responde a cualquiera, con Access-Control-Allow-Origin: *, y si llama a OpenAI o envía correos, cualquiera puede gastar tu cuota. Exige el JWT del usuario, limita el origen y pon un tope de peticiones por usuario.
  • Buckets públicos para archivos de usuarios. Lovable crea el bucket público porque así las imágenes "se ven". Para documentos privados, bucket privado y URL firmadas.
  • Invisible para la IA y los buscadores. La app es una SPA de Vite: el HTML llega vacío y los bots de ChatGPT o Perplexity no ven nada. Si la landing y el blog importan, sepáralos de la app. Detalle en por qué las apps hechas con IA son invisibles para la IA.
  • Sin cabeceras de seguridad ni metadatos. Ni CSP, ni HSTS, ni X-Frame-Options, y el título es el de la plantilla. Lo primero exige desplegar fuera de lovable.app; lo segundo se arregla con un prompt.
  • Validación solo en el formulario. El campo tiene maxLength pero la Edge Function o la tabla aceptan lo que llegue. Valida también en el servidor y en las restricciones de la base de datos.

Un bloque para la sección Knowledge de tu proyecto

En los ajustes del proyecto, Lovable tiene una sección de conocimiento que el modelo lee en cada petición. Pega esto para que las reglas se apliquen desde el primer prompt:

Reglas de seguridad de este proyecto:
- Toda tabla nueva lleva RLS activado y una política explícita por operación. Nunca uses using (true) ni with check (true) salvo en tablas de contenido público de solo lectura, y dímelo cuando lo hagas.
- Nunca pongas claves secretas en el código del frontend. Las integraciones con claves secretas van en una Edge Function que lee el secreto con Deno.env.get.
- Toda Edge Function comprueba el JWT del usuario salvo que yo diga lo contrario, limita Access-Control-Allow-Origin a nuestro dominio y valida la entrada.
- Los permisos de administrador se comprueban en RLS o en el servidor, nunca solo en el frontend.
- Los archivos subidos por usuarios van a buckets privados con políticas y URL firmadas.
- Las columnas role, is_admin, plan y credits no son editables por el usuario.
- Pon título, meta descripción y etiquetas Open Graph reales en index.html.

Un prompt de revisión antes de publicar

Revisa la seguridad de este proyecto y no cambies nada todavía. Responde con una lista:
1. Tablas sin RLS y políticas con using (true) o with check (true).
2. Claves o tokens presentes en el código del frontend, con el archivo y la línea.
3. Edge Functions que no comprueban el JWT, que responden con Access-Control-Allow-Origin: * o que no validan la entrada.
4. Rutas o acciones de administrador protegidas solo en el frontend.
5. Buckets públicos con archivos de usuarios.
6. Columnas de privilegio que un usuario puede modificar.
7. Metadatos del index.html que sigan siendo los de la plantilla.
Para cada punto, propón el cambio exacto y espera mi confirmación.

Comprueba el resultado desde fuera

Abre tu app publicada en una ventana de incógnito, clic derecho, "Ver código fuente", y busca service_role, sk_live, sk- y Bearer en los archivos JavaScript que carga. Después prueba la API de Supabase sin sesión:

curl -s "https://TU_PROYECTO.supabase.co/rest/v1/profiles?select=*" -H "apikey: TU_CLAVE_ANON" -H "Authorization: Bearer TU_CLAVE_ANON"

Si devuelve filas, esa tabla está abierta. Scanaris hace esto y unas cuarenta comprobaciones más en 30 segundos: detecta que la app es de Lovable, prueba las tablas de Supabase sin sesión, busca secretos en el bundle, revisa cabeceras, cookies, CORS y archivos expuestos, y comprueba si tu contenido es legible sin JavaScript. Por cada fallo te da un fix prompt para pegar en el chat de Lovable con el cambio exacto, y puede volver a escanear cada día porque una regeneración de código puede devolver un fallo que ya habías arreglado.

Preguntas frecuentes

¿Lovable ya arregló el problema del RLS?

Lovable añadió una revisión de seguridad antes de publicar y mejoró las plantillas, pero el modelo sigue generando políticas abiertas cuando una consulta falla. La responsabilidad de RLS es tuya: usa las consultas de la guía de Supabase.

¿Puedo poner cabeceras de seguridad en una app alojada en lovable.app?

No desde Lovable. Si las necesitas, sincroniza con GitHub y despliega en Vercel o Netlify, donde se configuran con un archivo. La app sigue editándose en Lovable.

¿Qué hago si pegué una clave secreta en el chat?

Rótala en el servicio de origen aunque ya no esté en el código: el historial del chat y los bundles anteriores la conservan. Después añádela por el cuadro de secretos y pide al modelo que mueva la integración a una Edge Function.

Checks relacionados

¿Tu app Lovable pasa estos checks?

Escanéala gratis y recibe un prompt de arreglo por cada fallo que encontremos.

Escanear mi web gratis