El código que genera la IA funciona, pero ¿es seguro?
Hace poco un cliente me pidió que revisara la seguridad de su VPS. Tenía varios servicios corriendo con Docker y Traefik como reverse proxy. Todo funcionaba bien, llevaba meses así, sin problemas aparentes.
Lo que encontré me hizo replantearme cómo usamos los LLMs para generar configuraciones.
El hallazgo que nos quitó el sueño
Entre los servicios desplegados había una aplicación de facturación. La había montado con ayuda de Claude, funcionaba perfectamente, tenía autenticación básica configurada en Traefik… todo correcto, ¿no?
No.
El docker-compose tenía esto:
services:
facturas:
image: app-facturas
ports:
- "8000:8000"
# ... resto de config
¿Ves el problema? Ese ports: "8000:8000" expone el contenedor directamente al mundo, sin pasar por Traefik. El auth_basic que tan cuidadosamente había configurado solo protegía las peticiones que llegaban por el dominio a través del proxy.
Pero cualquiera podía hacer:
curl http://su-ip:8000/api/invoices
Y obtener un JSON con todas las facturas. Clientes, importes, fechas, todo. Sin contraseña, sin SSL, sin nada.
Por qué los LLMs generan código inseguro por defecto
Cuando le pides a Claude, GPT o cualquier LLM que te genere un docker-compose, su objetivo es darte algo que funcione. Y la forma más directa de que funcione es exponer el puerto:
# Lo que genera la IA
ports:
- "8000:8000"
Funciona. Arrancas el contenedor, abres el navegador, ves tu app. Éxito.
Pero “funciona” no significa “está listo para producción”. El LLM no sabe (ni pregunta) si:
- Vas a poner esto detrás de un reverse proxy
- Necesitas que sea accesible solo localmente
- Tienes un firewall configurado
- Es un entorno de desarrollo o producción
La IA optimiza para el camino más corto hacia un resultado visible, no para seguridad. Y esto no es un bug, es una limitación inherente del contexto en el que operan estos modelos.
Si te interesa el tema de seguridad e IA, también escribí sobre cómo la IA se ha convertido en un nuevo vector de fuga de datos.
La solución: tres niveles de exposición
Dependiendo de tu caso, hay tres formas de manejar los puertos en Docker:
Nivel 1: Expuesto al mundo (casi nunca lo quieres)
ports:
- "8000:8000" # Equivale a 0.0.0.0:8000:8000
Úsalo solo si realmente necesitas acceso externo directo Y tienes otras capas de seguridad (firewall, autenticación en la app, etc.).
Nivel 2: Solo localhost
ports:
- "127.0.0.1:8000:8000"
El servicio solo es accesible desde la propia máquina. Útil si tu reverse proxy corre en el host (no en Docker) o para herramientas de administración.
Nivel 3: Solo red interna de Docker (lo recomendado con Traefik)
expose:
- "8000"
# Sin "ports", el contenedor solo es accesible
# desde otros contenedores en la misma red
Si usas Traefik u otro proxy dentro de Docker, esto es lo más seguro. El tráfico externo pasa obligatoriamente por el proxy, donde tienes tu SSL, auth, rate limiting, etc.
Checklist de seguridad post-IA para docker-compose
Cada vez que un LLM te genere un docker-compose, revisa esto antes de desplegarlo:
- ¿Tiene
portsdefinidos? → Pregúntate si realmente los necesitas - ¿El puerto está bindeado a 0.0.0.0? → Cámbialo a 127.0.0.1 o usa
expose - ¿Usas reverse proxy? → Los servicios deberían usar
expose, noports - ¿Hay variables de entorno con secretos? → Muévelas a un .env o Docker secrets
- ¿El contenedor corre como root? → Añade
user: "1000:1000"si es posible - ¿Tiene acceso a Docker socket? → Solo si es estrictamente necesario
Cómo pedir configuraciones más seguras desde el principio
En lugar de pedir:
“Genera un docker-compose para una app Node en el puerto 8000”
Prueba con:
“Genera un docker-compose para una app Node que irá detrás de Traefik. No debe exponer puertos directamente, solo a través de la red interna de Docker. Incluye labels de Traefik para el routing.”
Dar contexto sobre tu infraestructura ayuda al LLM a generar algo más adecuado. No es infalible, pero reduce las probabilidades de meter la pata.
Conclusión
Los LLMs son herramientas increíbles para acelerar el desarrollo, pero no sustituyen el conocimiento de seguridad. Cada línea de código generada por IA debería pasar por el mismo escrutinio que el código de un junior: funciona, pero ¿es correcto?
La app de mi cliente llevaba meses expuesta. Funcionaba perfectamente. Pero “funciona” y “está bien” no son lo mismo.
Haz la auditoría. Revisa tus docker-compose. Tu yo del futuro te lo agradecerá.
También te puede interesar
La IA es el nuevo canal de fuga de datos (y nadie está preparado)
Empleados copian datos sensibles en ChatGPT sin pensar. El phishing con IA es más sofisticado que nunca. La seguridad tradicional no sirve.
La gran mentira de los copilots: por qué el 95% de las empresas no ven resultados
Estudios de METR, MIT y California Management Review revelan que la IA no mejora la productividad como prometían. Análisis de datos reales y qué están haciendo las empresas que sí ven resultados.
OpenClaw: El Asistente de IA Viral que No Voy a Instalar (Todavía)
42.000 instancias expuestas, vulnerabilidades críticas y tres rebrandings en tres meses. Por qué el proyecto más comentado del momento me genera más dudas que entusiasmo.