Resumen ejecutivo
En mayo de 2025 un investigador encontró un 0-day remoto en el kernel de Linux usando solo la API de un modelo de lenguaje: sin framework agéntico, sin herramientas, sin andamiaje. Pero el dato que importa no es ese, sino el que vino después: con 3.300 líneas de contexto curado el modelo halló el bug en 8 de cada 100 corridas; con 12.000 líneas, en 1 de cada 100. Más contexto significó peor resultado. De esa observación parte HexFlaw, la herramienta que Matías Tillerías presentó en el I Congreso IA-LATAM: en vez de subirle el repositorio entero al modelo y pedirle "buscá vulnerabilidades", construye un grafo de llamadas desde el AST, parte desde las operaciones peligrosas hacia atrás y le entrega al modelo solo el camino relevante, ya anotado. El flujo produjo cuatro advisories públicos en dos proyectos open source, incluida una contaminación de prototipo con CVSS 8.5 que tumbaba un servicio multi-tenant.
1. El puntapié: un 0-day encontrado por un modelo
La charla arranca con el caso que cambió la conversación. Mayo de 2025: Sean Heelan auditaba ksmbd, el servidor SMB3 que corre dentro del kernel de Linux. El resultado fue CVE-2025-37899, un use-after-free en el manejador del comando SMB logoff — una falla que exige razonar sobre conexiones concurrentes que comparten una sesión, no el tipo de error que se detecta con una expresión regular. Y se encontró sin scaffolding, sin framework agéntico y sin herramientas: solo la API del modelo. Fue la primera discusión pública de un bug de esa naturaleza hallado por un LLM.
Lo revelador vino al medir la repetibilidad. Mismo modelo, mismo bug, distinto contexto:
corridas exitosas con 3.300 líneas de contexto curado
con 12.000 líneas: el mismo bug se pierde
relación señal-ruido reportada por el propio autor
Esa es toda la tesis en tres números: el cuello de botella no es la capacidad del modelo, es la calidad del contexto que recibe.
2. El antipatrón: «acá está mi repo, buscá vulnerabilidades»
Es la forma en que casi todo el mundo usa IA para revisar código, y es la peor. Al subir el repositorio completo, el modelo salta de un archivo a otro sin hilo conductor, gasta contexto en código irrelevante y termina con peor capacidad de recuperación que con un fragmento bien elegido. Más contexto, más alucinación.
La alternativa es preparar el contexto: entregarle solo el camino relevante para que se concentre en un flujo. Menos alucinación, más señal. El problema es que preparar ese camino a mano, en un repositorio grande, es inviable — y ahí entra la herramienta.
3. El enfoque: empezar por el sink, no por la entrada
Antes del método, tres palabras que la charla define para que nadie se pierda: SAST es revisar el código sin ejecutarlo buscando fallas de seguridad; el sink es la operación peligrosa, el lugar donde el dato del atacante hace daño; y BFS es recorrer un grafo por niveles, lo que garantiza el camino más corto sin perderse.
La decisión central de diseño es contraintuitiva: no se parte desde las entradas del sistema, se parte desde el peligro. Recorrer todas las entradas posibles explota combinatoriamente; en cambio, ubicar primero las operaciones peligrosas —ejecución de comandos, consultas a base de datos, escrituras de memoria— acota el problema desde el primer paso. Recién ahí el modelo revisa esos candidatos y marca cuáles parecen explotables, y luego se reconstruye el camino hacia atrás hasta una entrada controlable por el atacante.
4. El pipeline, etapa por etapa
La herramienta se organiza en cinco módulos, y el detalle importante es cuáles usan modelo de lenguaje y cuáles no: el grafo y la ingesta son determinísticos; el LLM solo entra donde hace falta juicio.
| Módulo | Qué hace | ¿LLM? | Salida |
|---|---|---|---|
| M1 · Ingesta | Fragmenta el código por AST, no por líneas | No | Chunks |
| M2 · Target | Acota a una funcionalidad concreta | Solo en discovery | Chunks rankeados |
| M3 · Code graph | Construye el grafo de llamadas | No | Grafo |
| M4 · Static | Detecta candidatos a vulnerabilidad | Sí | Hallazgos preliminares |
| M5 · Taint | Confirma el camino entrada → sink | Sí | Hallazgos confirmados |
Por qué AST y no expresiones regulares. Un abstract syntax tree entiende la estructura del programa, no su texto. El texto dice sp.run; el AST sabe que eso es subprocess.run porque resolvió el alias del import. El texto ve self.execute() y podría confundirlo con una ejecución de comandos; el AST distingue de qué clase es ese método. Y hay una regla de oro que evita ruido: ante la duda, no se emite arista — mejor un grafo conservador que uno lleno de caminos falsos.
Qué recibe finalmente el modelo. Ni el repositorio ni un fragmento suelto: el código más todo lo que el grafo ya dedujo sobre él — el rango de líneas absoluto (no lo estima), el rol de cada elemento (si es punto de entrada, si es sink y de qué clase) y el flujo entrante y saliente, indicando si viene sanitizado o no. El modelo no adivina el contexto: se lo entregan resuelto.
Cada hallazgo termina en uno de cuatro estados: confirmed (camino entrada→sink sin sanitizar), conditional (hay mitigación, pero es evadible), false_positive (el modelo concluyó que no es explotable) y needs_review (ambiguo, se re-evalúa). Esa taxonomía es lo que convierte una lista de sospechas en una cola de trabajo priorizable.
5. Hallazgos reales: cuatro advisories públicos
El método no se quedó en la demo. Con este mismo flujo se reportaron y publicaron cuatro vulnerabilidades en dos proyectos open source:
| Proyecto | Vulnerabilidad | CWE | Severidad |
|---|---|---|---|
| Wallos | Toma de cuenta vía OIDC | 287 | Alta · 8.1 |
| Wallos | SSRF vía SMTP de usuario | 918 | Moderada · 4.3 |
| trigger.dev | Contaminación de prototipo | 1321 | Alta · 8.5 |
| trigger.dev | Escritura no autenticada | 306 | Moderada · 5.3 |
El caso más elegante es la contaminación de prototipo en trigger.dev. El endpoint PUT /api/v1/runs/:runId/metadata aceptaba operaciones con una clave arbitraria; esa clave viajaba sin validación hasta un setter de rutas — ahí estaba el sink. Enviando $.__proto__.polluted se contamina el Object.prototype del proceso completo, lo que rompe la autenticación de otros inquilinos de la plataforma y voltea la aplicación: una denegación de servicio multi-tenant desde un endpoint con permisos mínimos.
El segundo hallazgo propio en ese mismo proyecto es igual de inquietante para cualquiera que despliegue agentes: en los Realtime Streams, cualquiera podía escribir en el stream de un agente. Lo que el usuario leía como respuesta del modelo, lo escribía un tercero.
6. Proteger al analizador del código que analiza
Hay un pliegue que la charla no esquiva: una herramienta que lee código hostil es, ella misma, un blanco. El código bajo análisis puede contener instrucciones dirigidas al modelo — inyección de prompt por la puerta de servicio. De ahí la insistencia en el principio de mínimo privilegio para sistemas de IA, que el OWASP Top 10 para LLM recoge como Excessive Agency: cuando el modelo tiene más permisos de los que necesita, alguien puede engañarlo para que los use.
7. Conclusiones
Tres ideas para llevarse. Primero, más contexto no es mejor contexto: la evidencia del caso ksmbd muestra una caída de 8 a 1 acierto por cada cien intentos al cuadruplicar el material entregado. Segundo, el trabajo determinístico debe hacerlo la máquina determinística: construir el grafo desde el AST, resolver alias y trazar caminos no requiere un LLM — y hacerlo antes de invocarlo es lo que convierte al modelo en un buen juez en lugar de un mal buscador. Tercero, esto ya encuentra cosas reales: cuatro advisories públicos, uno de ellos capaz de tumbar un servicio multi-tenant, salieron de este flujo.
El corolario para quien hace seguridad ofensiva en la región: la ventaja no está en tener acceso al modelo más caro, sino en saber qué ponerle delante. Ese es un trabajo de ingeniería y de criterio — y ahí LATAM compite de igual a igual.
Referencias
- Tillerías Ley, M. (2026). De código a exploit: análisis de vulnerabilidades con IA y grafos AST [presentación]. I Congreso IA-LATAM. PDF de la charla.
- Tillerías Ley, M. (2026). ¿Cómo puede la IA analizar código y descubrir rutas que podrían convertirse en CVE? [video]. Canal de Comunidad IA LATAM en YouTube. youtube.com/watch?v=lJANz84xtuc.
- CVE-2025-37899 — use-after-free en el handler de SMB logoff de ksmbd (kernel de Linux), hallado por Sean Heelan con la API de o3 (mayo de 2025), citado como caso de partida en la charla.
- OWASP Top 10 para aplicaciones con LLM — Excessive Agency, referenciado en la sección de seguridad por diseño.
- SecureHex: securehex.cl.
Sobre el autor
Matías Tillerías Ley es gerente general de SecureHex (Chile), consultora de seguridad ofensiva especializada en pentesting, hardening, ISO 27001 y formación. Es ingeniero en Telecomunicaciones, Conectividad y Redes, cursa un Bachelor in Cybersecurity en Southern New Hampshire University, y es miembro de OWASP Chile y socio de la CCHIA. En la Comunidad IA LATAM es director de Tecnologías (CIO y CAIO). HexFlaw, la herramienta de esta charla, nació del cruce entre su trabajo de pentesting y los modelos de lenguaje. LinkedIn
Artículo elaborado por la Comunidad IA LATAM a partir de la presentación oficial y la transcripción del video de la charla. Las vulnerabilidades citadas fueron divulgadas responsablemente y sus advisories son públicos. Este contenido se comparte con fines educativos y de seguridad defensiva.