Seguridad por stack

Seguridad para apps hechas con IA

Las apps vibe-coded se lanzan en horas, pero los básicos de seguridad —secretos expuestos, reglas de base de datos ausentes, CORS abierto, cabeceras que faltan— se quedan por el camino. Esta guía explica, sin jerga, los fallos que de verdad afectan a las apps hechas con IA, por qué se repiten una y otra vez, cómo comprobarlos tú mismo en diez minutos o con un escáner en 30 segundos, y qué vigilar después de lanzar.

Qué significa "seguridad en vibe coding"

Las herramientas de IA (Lovable, Bolt, v0, Cursor, Replit, Windsurf) generan apps con una arquitectura muy concreta: el navegador habla directamente con la base de datos (Supabase, Firebase) y con servicios externos (Stripe, OpenAI, Resend). Casi no hay servidor propio en medio. Eso acelera todo, pero mueve la seguridad de tu código a tu configuración: lo que te protege son las reglas de la base de datos, las cabeceras HTTP, la política de CORS y qué claves viven dónde, no lo limpio que esté el código de la interfaz.

Esas piezas no vienen bien puestas por defecto, y la IA rara vez las configura si no se lo pides. Su objetivo es que la app funcione en la demo, y una tabla sin restricciones o una clave pegada en el frontend "funcionan" perfectamente. El resultado son apps que se ven impecables y que exponen datos o claves a cualquiera que sepa mirar: no hace falta ser hacker, basta con abrir las herramientas de desarrollador del navegador.

Por eso "seguridad en vibe coding" no significa aprender criptografía ni contratar una auditoría. Significa conocer la media docena de fallos que se repiten en casi todas las apps hechas con IA, saber comprobarlos desde fuera y pedirle a la misma IA que los arregle con instrucciones precisas.

Por qué las apps hechas con IA fallan en lo mismo

Hay un patrón. La IA optimiza para que el código compile y la pantalla muestre datos, no para que un desconocido no pueda verlos. Cuando una consulta falla por permisos, la solución más corta es quitar el permiso que estorba: desactivar Row Level Security, poner una regla que lo permita todo o usar la clave de administrador. Y la IA elige la solución más corta.

El segundo motivo es que copia plantillas. Las variables con prefijo NEXT_PUBLIC_, VITE_ o NUXT_PUBLIC_ se envían al navegador por diseño, y muchos ejemplos de internet colocan ahí claves que nunca deberían salir del servidor. Las reglas de Firebase en modo de prueba permiten leer y escribir a cualquiera durante 30 días, y se lanzan apps con ese modo activo. Las cabeceras de seguridad no aparecen en casi ningún tutorial, así que tampoco aparecen en la app.

El tercero es que nadie dibuja el modelo de amenaza. Quien construye con IA piensa en el usuario que quiere, no en el visitante que abre la pestaña Network, copia la URL de la API y le quita el filtro. Esta guía va de ponerse en el lugar de ese visitante durante diez minutos.

Los siete fallos que más afectan a las apps hechas con IA

Claves de API en el navegador. Al "conectar" un servicio, la clave acaba en el JavaScript del cliente, donde es pública para siempre: cualquiera puede leerla viendo el código fuente y usarla a tu costa (facturas de OpenAI, correos enviados desde tu dominio, acceso a tus datos). Las únicas claves que pueden ir al cliente son las diseñadas para ello, como la clave anon o publishable de Supabase, la clave pública de Stripe o la configuración de Firebase, y solo si las reglas que hay detrás están bien.

Reglas de base de datos ausentes o débiles. Sin Row Level Security activado en cada tabla de Supabase, o con una política que lo permite todo, cualquiera lee y escribe tus datos sin iniciar sesión usando la misma API que usa tu app. En Firebase, las reglas en modo de prueba o con allow read, write: if true hacen lo mismo. Es el fallo más grave y el más frecuente, y fue el origen de la vulnerabilidad CVE-2025-48757 que expuso datos de usuarios en apps hechas con Lovable.

CORS permisivo. Una API que responde con Access-Control-Allow-Origin reflejando cualquier origen y además permite credenciales deja que una web maliciosa haga peticiones en nombre de tus usuarios y lea las respuestas. El comodín en una API pública sin cookies es aceptable; reflejar el origen con credenciales, nunca.

Cabeceras de seguridad ausentes. Sin Content-Security-Policy, Strict-Transport-Security, X-Frame-Options (o frame-ancestors), X-Content-Type-Options, Referrer-Policy y Permissions-Policy, tu app queda expuesta a clickjacking, inyección de scripts, degradación a HTTP y fugas de URLs internas. Se configuran en el servidor o en el hosting (Vercel, Netlify, Cloudflare) en diez líneas.

Archivos sensibles accesibles. Un .env publicado por error, un directorio .git expuesto, source maps que permiten reconstruir el código fuente completo, backups de la base de datos o paneles de administración sin autenticación. Son fáciles de encontrar porque los atacantes los buscan de forma automática en cada dominio nuevo que aparece.

Sesiones y cookies mal configuradas. Cookies de sesión sin los atributos Secure, HttpOnly y SameSite, tokens guardados en localStorage al alcance de cualquier script, o sesiones que no caducan nunca. Un XSS pequeño se convierte en robo de cuentas cuando la cookie es legible desde JavaScript.

Endpoints que confían en el cliente. Rutas de API que aceptan el identificador de usuario, el precio o el rol desde el cuerpo de la petición sin comprobarlo en el servidor. Si la interfaz oculta el botón de administrador pero la ruta sigue respondiendo a cualquiera, el botón no protege nada.

Qué revisar según tu stack

Lovable, Bolt o v0 con Supabase. Revisa que todas las tablas tengan RLS activado y políticas por operación (select, insert, update, delete) basadas en auth.uid(); que la clave service_role no esté en ninguna variable pública; que los buckets privados de Storage tengan políticas; y que las vistas y funciones RPC no se salten las políticas. El panel de Supabase incluye un Security Advisor que lista lo más grave.

Cursor, Windsurf o Replit con Next.js, Nuxt o Express desplegado en Vercel. Comprueba qué variables de entorno llevan prefijo público, que las rutas de API validan la sesión en cada petición y no solo en la interfaz, que las cabeceras de seguridad están definidas (vercel.json, next.config o nuxt.config) y que no se publican source maps en producción.

Firebase. Sustituye las reglas de modo de prueba por reglas basadas en request.auth, tanto en Firestore como en Storage; activa App Check para que solo tu app pueda usar tus servicios; y revisa que las Cloud Functions que hacen algo sensible comprueben el token del usuario antes de actuar.

Que la app "se vea bien" no significa que sea segura

Ocultar un botón en la interfaz no protege nada: la petición sigue siendo una URL pública que cualquiera puede llamar directamente desde la consola del navegador o con curl. La seguridad de verdad vive en el servidor y en la base de datos, no en lo que el usuario ve. Por eso comprobarlo desde fuera —como lo haría un atacante— es la única forma de saber qué está realmente expuesto.

Tampoco basta con que el candado HTTPS esté en verde. HTTPS cifra el camino entre el navegador y tu servidor; no dice nada sobre si el servidor entrega datos a quien no debe. Una app con certificado perfecto y una tabla sin RLS es una app con una fuga perfectamente cifrada.

Cómo comprobarlo tú mismo en diez minutos

Uno: abre tu web y mira el código fuente (clic derecho, ver código fuente). Busca key, secret, sk_, service_role y los nombres de los servicios que uses. Todo lo que aparezca ahí es público.

Dos: con la app abierta, ve a la pestaña Network de las herramientas de desarrollador, localiza una petición a tu base de datos o a tu API, copia la URL y ábrela en una ventana de incógnito. Si devuelve datos sin sesión, ese endpoint está abierto. Con sesión, quítale el filtro de usuario a la URL: si devuelve filas de otros, las políticas están mal.

Tres: pide las cabeceras de tu dominio con curl -I https://tudominio.com y comprueba si aparecen Content-Security-Policy, Strict-Transport-Security y X-Frame-Options o frame-ancestors. Si falta alguna, no está configurada.

Cuatro: prueba a abrir /.env, /.git/config, /config.json y algún archivo .js.map de tu bundle. Todos deben devolver 404 o 403.

Cinco: crea dos cuentas de prueba y comprueba que ninguna ve, edita ni borra lo de la otra, incluidos los archivos subidos. Es la prueba más aburrida y la que más fallos encuentra.

Cómo comprobarlo en 30 segundos

Scanaris automatiza esas pruebas y unas cuantas más. Escanea tu web ya publicada en modo solo lectura: no toca tu código, no inyecta nada ni intenta explotar nada; mira lo que ya es público, como lo haría cualquiera desde fuera. Comprueba cabeceras, cookies, certificado TLS, CORS, secretos en el JavaScript, archivos sensibles, tecnologías con versiones conocidas, las reglas de Supabase si le das una conexión de solo lectura, y además cómo te ve Google y cómo te leen las IA.

Cada hallazgo viene ordenado por impacto (primero lo crítico), explicado en lenguaje normal y con un prompt de arreglo listo para pegar en Lovable, Cursor o la herramienta que uses. Pega tu URL, espera medio minuto y sabrás si puedes compartir tu app con tranquilidad.

Qué vigilar después de lanzar

La seguridad no es un estado, es un hábito. Cada tabla nueva nace sin RLS, cada función nueva puede meter una clave en el sitio equivocado y cada dependencia envejece. Programa un re-escaneo periódico y revisa las diferencias, no el informe entero: lo importante es qué se ha abierto desde la última vez.

Vigila también lo que no depende del código: que el certificado y el dominio no caduquen, que la web responda, y que en el navegador de tus usuarios no aparezcan scripts que tú no pusiste. Y cuando arregles algo, vuelve a comprobarlo desde fuera: el arreglo cuenta cuando el escáner deja de verlo, no cuando la IA dice que está listo.

Escanear mi web gratis

Profundiza según tu stack

Comprobaciones de seguridad clave

Guías relacionadas

Preguntas frecuentes

¿Es segura mi app hecha con Lovable, Bolt o Cursor?

Puede serlo, pero por defecto suele salir con claves en el frontend, reglas de base de datos incompletas y sin cabeceras de seguridad. La única forma de saberlo es comprobar tu web ya publicada: Scanaris lo hace en 30 segundos, en modo solo lectura.

¿Tener HTTPS significa que mi app es segura?

No. HTTPS cifra la conexión entre el navegador y tu servidor, pero no impide que el servidor entregue datos a quien no debe. Una tabla sin RLS o una clave en el frontend siguen expuestas con el candado en verde.

¿Escanear mi web es peligroso para mi sitio?

No. Scanaris hace comprobaciones de solo lectura sobre información ya pública (cabeceras, cookies, certificados, archivos accesibles). No modifica, borra ni inyecta nada. Solo debes escanear webs propias o para las que tengas autorización.

¿En qué se diferencia esto de un pentest?

Un pentest es un trabajo manual de días hecho por especialistas que intentan explotar tu app con autorización. Scanaris es una revisión automática, de solo lectura y en segundos, de los fallos de configuración que se repiten en las apps hechas con IA. Cubre lo que más veces falla; no sustituye a un pentest si manejas datos muy sensibles.

¿Necesito saber de seguridad para usarlo?

No. Cada hallazgo viene con una explicación clara y un prompt de arreglo listo para pegar en tu IA, así que puedes solucionarlo sin ser experto. Pega el prompt, revisa el cambio y vuelve a escanear para confirmar que se ha cerrado.

¿Cada cuánto debería volver a escanear?

Cada vez que la IA toque la base de datos o añada una integración, y como mínimo cada semana si la app está en producción. Los planes de pago lo hacen solos y te avisan únicamente cuando cambia algo.