Un almacén de barrio no te deja entrar al depósito. No importa cuánto confíes en el dueño — hay cosas que no son para todo el mundo. El stock, los proveedores, los precios reales. Hay una línea que separa lo que se muestra del mostrador de lo que sostiene el negocio.
La supply chain de software es exactamente eso: el depósito. Y durante años la tratamos como si fuera el mostrador. Abierto, luminoso, accesible. Confiando en que los proveedores son quienes dicen ser.
Después llegó la IA y ampliamos el depósito sin agregar cámaras.
Project Glasswing software supply chain security AI: de qué estamos hablando
Glasswing es una iniciativa de investigación enfocada en el problema que la industria está eligiendo no mirar de frente: cuando usás IA para generar código, para revisar dependencias, para sugerir arquitecturas — ¿quién audita al auditor?
La premisa es simple y me clavó justo donde duele. Tenemos pipelines de CI/CD que corren checks automáticos. Tenemos Dependabot, Snyk, Trivy. Tenemos SBOMs. Pero ahora también tenemos:
- Código generado por LLMs que sugieren librerías con nombres plausibles pero que no existen (hallucinated packages)
- Agentes de IA que tienen acceso a nuestros repos y ejecutan comandos
- Modelos fine-tuneados con código de dudosa procedencia
- Contexto de negocio que le pasamos a APIs externas sin pensar demasiado
Cada uno de esos puntos es una puerta al depósito. Y la mayoría de nosotros no le pusimos llave todavía.
Estaba pensando en esto justo cuando escribí sobre Scion, el framework de Google para orquestar agentes. Ahí lo planteé como una herramienta interesante. Hoy lo miro con otros ojos: ¿cuál es el modelo de permisos cuando un agente puede llamar a otro? ¿Quién audita las acciones de la cadena completa?
El problema concreto: qué cambió con AI-assisted coding
Voy a ser honesto sobre mi propia práctica antes de sonar a evangelista de seguridad.
Yo uso IA en proyectos reales. Todos los días. Lo expliqué con bastante detalle en vibe-coding vs stress-coding: hay momentos donde la IA acelera y momentos donde te lleva a un callejón. Pero lo que no había mapeado bien hasta ahora era el vector de ataque específico.
Estos son los tres que Glasswing pone en el centro:
1. Package hallucination
Los LLMs inventan nombres de paquetes. No siempre, pero lo hacen. Y cuando un atacante ve que GPT-4 consistentemente sugiere react-auth-utils para un caso de uso específico — un paquete que no existe — puede registrar ese nombre en npm y esperar.
Se llama dependency confusion con un giro nuevo: en vez de explotar paquetes privados, explotan las alucinaciones del modelo.
# Antes de instalar CUALQUIER cosa que te sugirió una IA, verificá:
npm view nombre-del-paquete --json | grep -E '"name"|"version"|"author"|"downloads"'
# Si el paquete tiene menos de un mes de vida y cero downloads, preguntate por qué
# Si no existe el comando va a tirar error — eso ya es información
2. Context leakage
Cuando le pasás contexto a un LLM para que genere código — schema de base de datos, variables de entorno de ejemplo, arquitectura del sistema — ese contexto sale de tu perímetro. Con APIs comerciales, las políticas de retención de datos varían. Con modelos fine-tuneados en código de terceros, el problema es diferente pero igual de real.
No es paranoia. Es superficie de ataque.
3. AI-generated code con vulnerabilidades no detectadas por scanners tradicionales
Este es el que más me preocupa. Los scanners de SAST buscan patrones conocidos. El código generado por IA puede tener vulnerabilidades semánticamente correctas — código que compila, pasa los tests, hace lo que se le pide — pero con lógica de autorización mal implementada o condiciones de carrera que ningún regex va a detectar.
// Código que un LLM podría generar y que parece correcto
async function getDocument(userId: string, docId: string) {
const doc = await db.documents.findOne({ id: docId });
// El LLM olvidó verificar que userId === doc.ownerId
// El scanner no lo detecta porque no hay un pattern de vulnerabilidad conocido
// Es lógicamente incorrecto, no sintácticamente
return doc;
}
// Lo que debería ser:
async function getDocument(userId: string, docId: string) {
const doc = await db.documents.findOne({
id: docId,
ownerId: userId // Siempre filtrá por ownership en la query, no después
});
if (!doc) {
throw new Error('Documento no encontrado o sin acceso');
}
return doc;
}
Qué cambié yo en mi pipeline
Después de leer la investigación de Glasswing y procesarla unos días, hice cambios concretos. No dramáticos, pero concretos.
1. Lock files como ciudadanos de primera clase
Siempre usé lock files, pero ahora los reviso activamente en code review. Un PR que toca pnpm-lock.yaml en más lugares de los esperados me hace parar. Cuando migramos de npm a pnpm el año pasado — esa migración que pasó el install de 14 minutos a 90 segundos — me di cuenta de cuántas dependencias transitivas existen sin que nadie las haya elegido conscientemente.
# Compará el lockfile antes y después de que la IA sugiera cambios
git diff pnpm-lock.yaml | grep '^+' | grep 'resolution' | wc -l
# Si el número es mucho mayor al de packages que agregaste explícitamente, investigá
2. SBOM generado en cada build
# En mi workflow de GitHub Actions
- name: Generar SBOM
uses: anchore/sbom-action@v0
with:
artifact-name: sbom.spdx.json
format: spdx-json
- name: Escanear SBOM contra vulnerabilidades conocidas
uses: anchore/scan-action@v3
with:
sbom: sbom.spdx.json
fail-build: true
severity-cutoff: high
3. Revisión manual de cualquier paquete sugerido por IA que no reconozco
Suena obvio. No lo era en la práctica. Cuando Copilot o Claude sugieren un import, tengo el hábito de terminar escribiéndolo sin pensar. Ahora tengo una regla personal: si no reconozco el paquete de memoria, abro npm antes de instalar.
Esto conecta con algo que mencioné cuando construí la extensión de certificados SSL: la confianza implícita es el enemigo. Un certificado puede parecer válido y no serlo. Un paquete puede parecer legítimo y no serlo.
4. Contexto mínimo necesario hacia APIs externas
Empecé a ser más intencional sobre qué le paso a un LLM. Schema completo de producción: no. Schema anonimizado o de ejemplo: sí. Variables de entorno reales: nunca. Estructura de carpetas completa con nombres de servicios internos: tampoco.
Es como el principio de least privilege pero para el contexto que compartís.
Los gotchas que nadie menciona
El falso positivo de "ya uso Dependabot"
Dependabot es necesario. No es suficiente. Dependabot sabe de vulnerabilidades conocidas y publicadas en bases de datos. No sabe de paquetes recién creados que imitan nombres de paquetes que los LLMs alucinan. No sabe de vulnerabilidades lógicas en código generado.
El problema del contexto de equipo
Cuando laburás solo, podés controlar qué le pasás a la IA. Cuando laburás en equipo, alguien más puede estar pegando el schema de prod en el chat de Claude sin que vos lo sepas. Eso requiere política, no solo práctica individual.
Confundir herramientas de seguridad con postura de seguridad
Tengo la extensión de HAProxy que documenté acá y la extensión de certificados. Soy cuidadoso con la infraestructura. Pero cuidado con infraestructura ≠ cuidado con supply chain. Son capas diferentes.
El score que te da confianza falsa
Así como el score de accesibilidad de Lighthouse puede mentirte porque mide lo que puede medir mecánicamente, el score de seguridad de tus herramientas mide lo que fue catalogado. La superficie de ataque nueva que trae la IA todavía no tiene métricas maduras.
FAQ: Project Glasswing y seguridad de supply chain con IA
¿Qué es exactamente Project Glasswing?
Es una iniciativa de investigación de seguridad enfocada en los nuevos vectores de ataque que introduce la IA en el ciclo de desarrollo de software. El nombre hace referencia a la mariposa Glasswing — transparente, delicada, más resistente de lo que parece. El foco está en cómo los modelos de lenguaje afectan la integridad de la software supply chain: desde package hallucination hasta vulnerabilidades semánticas en código generado automáticamente.
¿El package hallucination es un riesgo real o teórico?
Es real y ya hay casos documentados. Investigadores de seguridad probaron que es posible registrar paquetes con nombres que los LLMs populares sugieren consistentemente para casos de uso comunes. La tasa de hallucination varía por modelo y contexto, pero ninguno está en cero. El riesgo escala con la popularidad del modelo: cuanto más gente usa el mismo LLM, más predecible es qué nombres va a inventar.
¿Alcanza con tener Snyk o Dependabot en el pipeline?
No. Esas herramientas son esenciales pero cubren vulnerabilidades conocidas y catalogadas. El vector de AI-assisted coding introduce dos problemas que escapan a ese modelo: paquetes maliciosos que no están todavía en ninguna base de datos de vulnerabilidades, y vulnerabilidades lógicas en código generado que no tienen un pattern reconocible por análisis estático. Necesitás las capas, pero no podés parar ahí.
¿Cómo sé si el código que generó la IA tiene vulnerabilidades lógicas?
Esa es la pregunta difícil. Las herramientas de SAST tradicionales no están optimizadas para esto. Lo que funciona hoy: revisión humana con foco específico en lógica de autorización y manejo de datos sensibles, tests de seguridad funcionales (no solo unitarios), y — paradójicamente — usar otra IA para revisar el código generado por la primera, con un prompt específicamente orientado a buscar problemas de seguridad. No es perfecto, pero agrega una capa.
¿Qué información nunca debería pasarle a un LLM externo?
Credenciales reales, tokens, API keys — obvio. Pero también: esquemas de base de datos de producción con nombres de tablas y columnas reales, nombres de servicios internos y arquitectura de infraestructura, datos de usuarios aunque estén anonimizados parcialmente, y cualquier cosa que bajo tu modelo de amenaza sería valiosa para un atacante que supiera la estructura interna de tu sistema. La regla práctica: si no lo publicarías en un README público, no lo pegues en un chat de IA.
¿Los modelos que corro localmente (Ollama, LM Studio) tienen los mismos riesgos?
El riesgo de context leakage hacia APIs externas desaparece. Los riesgos de package hallucination y vulnerabilidades lógicas persisten — son propiedades del modelo, no del deployment. Si usás modelos locales, ganás control sobre dónde va tu contexto, pero igual necesitás revisar las sugerencias con el mismo criterio. No es seguridad por oscuridad, es reducir la superficie de ataque a la que tenés control.
Lo que no va a cambiar: la responsabilidad sigue siendo nuestra
Llevo 30 años con tecnología. Muchos de ellos en infraestructura — servidores, redes, la paranoia sana de alguien que tiró un servidor de producción con rm -rf en su primera semana y aprendió de la peor manera que la confianza implícita tiene costos reales.
Lo que me toca de Glasswing no es el alarmismo. Es el recordatorio de algo que debería ser obvio pero que la velocidad del ecosistema IA nos hace olvidar: cada herramienta nueva que acelera el desarrollo también expande la superficie que tenemos que defender.
No estoy diciendo que pares de usar IA para programar. Yo no voy a parar. Estoy diciendo que la misma energía que ponés en aprender a promptear bien la tenés que poner en entender dónde están las nuevas puertas del depósito.
El lock file es tuyo. El código generado es tuyo. La responsabilidad es tuya.
Si esto te hizo pensar en algo que tenés pendiente de revisar en tu pipeline, arrancá hoy. No tiene que ser todo a la vez. Un SBOM en CI, una policy de contexto para tu equipo, el hábito de verificar paquetes antes de instalarlos. Una puerta a la vez.
Comentarios (0)
Deja un comentario
Artículos Relacionados
LittleSnitch para Linux: por qué tardó tanto y qué dice eso del ecosistema
Llevo años desarrollando en Linux y la ausencia de un outbound firewall decente con GUI siempre fue el elefante en el cuarto. No es un review — es una excusa para hablar de por qué ciertas herramientas obvias tardan una década en aparecer en Linux.
Nunca más tipees openssl x509 -text -noout: creé una extensión de VS Code para ver certificados SSL/TLS
Harté de buscar el comando exacto de openssl cada vez que necesitaba inspeccionar un .pem o un .pfx. Creé X509 Certificate Utility para VS Code y cambió mi flujo de trabajo para siempre.
Cómo Linux ejecuta un binario: lo entendí a los 33 años de programar y me da vergüenza
33 años con computadoras y recién ahora entiendo qué pasa entre que escribís `./mi-programa` y corre el código. ELF, dynamic linking, ld-linux — el agujero negro que siempre esquivé.