En resumen
El código que escribe una IA suele funcionar. Lo que falla es quién puede llegar a los datos. En una auditoría de 2026 a 200 apps de vibe coding ya desplegadas, el 91% tenía al menos una vulnerabilidad y el control de acceso roto fue el grupo más grande. Reproduje cinco de esos huecos en un stack local de Supabase: solo con la clave pública, una tabla sin RLS, una política siempre verdadera, una vista y una secret key filtrada entregaron cada una las 3 filas de 3. Revise primero estos puntos en su app.
Soy Denys, ingeniero full-stack y de IA. Arreglo apps que se hicieron con Lovable, Bolt, Cursor o Claude Code, y la mayoría corre sobre Supabase. Este artículo reúne lo que dice la investigación publicada sobre la seguridad del vibe coding y lo que vi al reconstruir a propósito los errores más comunes.
¿Cuáles son los riesgos de seguridad del vibe coding?
El riesgo principal es el control de acceso roto: datos que cualquier visitante puede leer o cambiar porque falta la regla que debería detenerlo, es demasiado laxa o se la salta algo. Después vienen la inyección y la autenticación débil. Tres estudios independientes apuntan en la misma dirección:
| Estudio | Qué se probó | Qué encontró |
|---|---|---|
| Deng, Fan y Meng, arXiv 2606.23130, junio de 2026 | 200 apps desplegadas hechas con Claude Code y Lovable, auditadas a mano y con agentes | 182 de 200 apps (91%) tenían al menos una vulnerabilidad; el 65,77% de los 1.186 hallazgos eran críticos o altos; el control de acceso roto fue la categoría más grande, en el 64% de las apps |
| Escape, octubre de 2025 | 5.600 apps públicas de Lovable, Base44, Create.xyz y otras, con un escaneo pasivo | Más de 2.000 vulnerabilidades de alto impacto, más de 400 secretos expuestos, 175 casos de datos personales expuestos; la causa principal fueron permisos mal configurados, sobre todo el RLS de Supabase |
| Veracode GenAI Code Security Report, 2025 y 2026 | 80 tareas de programación dadas a más de 100 modelos | Solo el 55% de las tareas produjo código seguro en 2025; la tasa media de aprobación fue del 56% en 2026, sin cambios según el tamaño del modelo ni el año |
Los estudios miden cosas distintas, así que los porcentajes no suman un solo número. Lo que comparten es la forma: el código funciona y los huecos están en la frontera de confianza.
¿Qué huecos reproduje?
Preparé una tabla, orders, con tres filas de clientes falsos en un stack local de Supabase (CLI 2.109.1, Postgres 17.6, PostgREST 14.14). Después llamé a la Data API como lo hace un navegador, con la publishable key (clave publicable) que lleva todo frontend de Supabase, y cambié una sola cosa cada vez.
| Configuración | Qué obtuvo la clave pública | Por qué |
|---|---|---|
| Tabla sin RLS | Las 3 filas, y un insert devolvió 201 Created |
Los grants por defecto dejan a anon leer y escribir, y nada filtra las filas |
| RLS activado, sin política | [], una lista vacía |
RLS sin ninguna política lo deniega todo a anon y authenticated |
Política using (true) |
Las 3 filas | La política existe, así que la tabla parece protegida, pero permite todas las filas |
| Vista sobre la tabla protegida | Las 3 filas | Una vista se ejecuta con los derechos de su dueño salvo que tenga security_invoker = true; con él, [] |
| Secret key en el código del frontend | Las 3 filas | La secret key corresponde a service_role, que tiene BYPASSRLS |
La segunda fila es el momento peligroso. RLS está activado y la app muestra una lista vacía, así que parece rota. El prompt más rápido que la “arregla” es una política que lo permite todo, que es la tercera fila. Ese ciclo, error y después una corrección que amplía el acceso, es el patrón que más veo en apps de vibe coding, y por eso “RLS está activado” dice poco por sí solo.
¿Por qué el código escrito por IA falla en el control de acceso?
A un agente se lo recompensa por código que funciona. Una lista vacía o un 401 parecen un bug, y la corrección que los hace desaparecer suele ser la que abre el acceso. El estudio de arXiv rastrea sus 1.186 hallazgos hasta ocho modos de fallo recurrentes, agrupados como defectos de memoria, de objetivo y de conocimiento de los agentes, y concluye que mejorar los prompts redujo el número de huecos pero no los eliminó.
La segunda razón es la arquitectura. Una app de Lovable o Bolt normalmente no tiene un backend propio: el navegador habla directamente con la base de datos a través de la Data API. Toda regla que proteja los datos de los clientes tiene que vivir en Postgres, como grants, políticas y funciones, y nada de eso se ve en la vista previa de la app, donde usted ha iniciado sesión como propietario. Supabase cambia aquí un valor por defecto: desde el 30 de octubre de 2026, las tablas nuevas de los proyectos existentes ya no se conceden automáticamente a la Data API. En mi stack, una tabla sin el grant respondió 42501 permission denied con una pista que nombra el GRANT que falta. Eso frena la primera fila de la tabla anterior para las tablas nuevas, pero no las otras cuatro, ni las tablas que ya existen.
¿Qué más falla fuera de la base de datos?
Los mismos estudios listan riesgos que nada tienen que ver con RLS:
- Secretos en el bundle. Escape encontró más de 400 secretos expuestos, entre ellos claves de OpenAI y claves de administración de pagos. Todo lo que se envía al navegador es público.
- Guardas de ruta solo en React. Una página que redirige a los usuarios sin sesión sigue teniendo detrás una API que responde a cualquiera.
- Límites de peticiones que nunca saltan. En un proyecto alojado de Supabase que probé, un contador guardado en la memoria de una edge function se reiniciaba en cada petición. Lo conté en mi lista de seguridad para apps Lovable.
- Librerías antiguas. Escape contó 254 instancias de librerías JavaScript vulnerables en recursos públicos, a menudo heredadas de plantillas.
¿Cómo se revisa una app hecha con vibe coding?
- Abra la app, abra DevTools → Network y busque peticiones a
/rest/v1/. Cópiela como cURL, quite la cabeceraAuthorization, deje elapikeyy ejecútela. Si devuelve datos, también se los devuelve a cualquiera. - Busque
sb_secret_yservice_roleen el JavaScript compilado. Si hay una coincidencia, es una clave que hay que rotar hoy. - Ejecute la Auditoría de seguridad de Supabase gratuita. Lee el catálogo del proyecto y señala, entre sus 46 reglas, “RLS desactivado en tablas expuestas”, “Políticas que permiten todas las filas”, “Vistas que se saltan RLS” y “Privilegios por defecto que abren objetos nuevos a la API”: las cuatro primeras filas de la tabla anterior.
- Pruebe con dos usuarios de dos empresas, la única prueba que un escáner no puede hacer por usted. Cómo la hago está en la lista para Lovable, y cómo probar Supabase RLS muestra el método en una app de producción con una pantalla de permisos.
curl 'https://<project>.supabase.co/rest/v1/orders?select=*' \
-H 'apikey: <the publishable key from your page>'
Lo que esto no demuestra
Mi reproducción es una tabla en un stack local, montada para mostrar cada mecanismo, no un escaneo de apps reales. Las cifras de prevalencia vienen de los tres estudios, cada uno con su muestra y su método, enlazados arriba. Y un resultado limpio en estas cinco comprobaciones no hace segura una app: los bugs de lógica, como una guarda que deja pasar un valor ausente, necesitan sus propias pruebas. Uno de ellos está en un NULL que saltó una comprobación de permisos.
¿Hizo su app con una herramienta de IA?
Me gustaría comparar notas sobre qué revisar primero. Sin pitch.
Escríbame