La mayoría de herramientas de IA son muy buenas ayudándote a escribir código. Pero yo quería explorar una pregunta distinta:
¿Puede la IA ayudarte a encontrar los casos límite y los problemas de seguridad que no se te ocurrieron?
Esa pregunta me llevó a construir EdgeGuard, una extensión open source de VS Code diseñada para investigar el código desde una perspectiva adversarial. La idea es simple:
Intenta romper el código antes de que lo rompa producción.
Pero cuando probé la idea contra benchmarks reales de seguridad, descubrí un problema: la IA era demasiado optimista. Y OWASP lo expuso muy rápido.
La trampa de los falsos negativos
Empecé probando EdgeGuard contra el OWASP Benchmark para Java. Lo primero que noté fue sorprendentemente simple. Dado código como este:
String param = request.getParameter("id");
String bar = DatabaseHelper.doSomething(param);
String sql = "SELECT * FROM USERS WHERE ID='" + bar + "'";
El LLM podía ver la entrada HTTP no confiable. Podía ver la construcción del SQL. Pero no podía ver qué hacía realmente doSomething().
Entonces hacía una suposición optimista:
“Probablemente es un helper interno que sanitiza la entrada.”
Y el resultado podía ser SEGURO, aunque los datos seguían fluyendo hacia un sink de SQL. Este era exactamente el tipo de falso negativo que quería que EdgeGuard encontrara.
El problema no era que el modelo no entendiera la inyección SQL. El problema era que el modelo llenaba la información faltante con una suposición optimista.
Deja de adivinar sobre código desconocido
Cambié la estrategia de investigación. En lugar de enviar código crudo y preguntar “¿Es vulnerable?”, EdgeGuard ahora:
- Rastrea el flujo de datos desde las entradas hacia los sinks.
- Marca explícitamente el código desconocido como “no verificado” en lugar de asumir que es seguro.
- Cuando encuentra una función desconocida en medio de un flujo peligroso, la marca como candidata de alto riesgo y profundiza la investigación.
- Distingue entre “verificado seguro” y “no analizado” en el reporte final.
Este cambio fue crucial: la herramienta dejó de llenar vacíos con optimismo y empezó a señalarlos como lo que son: incógnitas que necesitan verificación.
El problema del costo: no todo merece un viaje al LLM
Si EdgeGuard enviara cada función al LLM, un proyecto con miles de funciones sería lento y caro. Crearía dos problemas inmediatos: límites de tasa de la API y costo.
Empieza con la solución más simple, y solo agrega complejidad cuando lo simple se rompe.
Así que agregué una etapa local de Evaluación Estática de Riesgo que corre directamente dentro de VS Code. Antes de hacer una llamada a la API, EdgeGuard parsea el código localmente y busca características que hacen que una función merezca investigación:
- sinks de base de datos
- acceso al sistema de archivos
- ejecución de procesos
- límites de red
- entrada controlada por el usuario
- APIs potencialmente peligrosas
- validación faltante
La etapa local actúa como filtro. En lugar de:
7,000 funciones
↓
LLM
↓
$$$$$$$$$
la arquitectura se convierte en:
7,000 funciones
↓
Evaluación Estática Local
↓
Riesgo Alto / Medio
↓
Investigación LLM
↓
Evidencia + Verificación
Esto convierte al LLM en un motor de razonamiento, no en la primera línea de análisis.
La prueba de estrés: 7,536 funciones
Quería saber si esta arquitectura funcionaba a escala de proyecto real. Cargué el proyecto completo OWASP Benchmark Java en VS Code y lancé un escaneo del workspace.
El escaneo descubrió:
- 7,536 funciones
- 2,771 archivos
La etapa de screening local filtró el código e identificó las funciones que merecían investigación profunda. El LLM se enfocó en los candidatos de mayor riesgo en lugar de procesar ciegamente cada función.
En esta prueba, EdgeGuard reportó 2,145 defectos potenciales, incluyendo:
- inyección SQL
- inyección de comandos
- flujos de datos inseguros
- otros caminos peligrosos de entrada a sink
Lo importante para mí no fue solo el número de hallazgos, sino que la arquitectura pudiera pasar de:
una función → una solicitud al LLM
a:
workspace completo → screening local → investigación dirigida con IA
sin convertir cada método en una llamada a la API.
Probando tres lenguajes
También quería que EdgeGuard funcionara más allá de Java. Probé la arquitectura contra proyectos en tres ecosistemas distintos:
Java
OWASP Benchmark
TypeScript
OWASP Juice Shop
C#
Microsoft eShopOnWeb
Esto introdujo otro problema: Java, C# y TypeScript tienen sintaxis, estructuras AST, convenciones, APIs de seguridad y estructuras de proyecto muy diferentes. No quería que la lógica de parsing específica por lenguaje se filtrara al motor de investigación.
Separé las capas de contexto por lenguaje:
EdgeGuard
│
Motor de Investigación
│
┌───────────┼───────────┐
│ │ │
Java C# TypeScript
Contexto Contexto Contexto
│ │ │
AST AST AST
La lógica de investigación se mantiene compartida mientras el contexto específico del lenguaje queda aislado. Un principio de diseño clave:
Comparte la lógica de investigación. Aísla el contexto específico del lenguaje.
Evidencia sobre suposiciones
Generar un reporte de vulnerabilidades no era suficiente. Una IA puede decir “esto podría ser vulnerable”. Pero lo que realmente quiero es: “así puedes reproducirlo”.
Para vulnerabilidades potenciales, EdgeGuard intenta construir contraejemplos de entrada y generar tests de verificación ejecutables:
- xUnit para C#
- JUnit para Java
- Mocha para TypeScript
El objetivo es pasar de:
La IA dice:
"Esto podría ser vulnerable."
a:
Hipótesis de IA
↓
Contraejemplo
↓
Test generado
↓
Ejecución
↓
Evidencia
El principio: evidencia sobre suposiciones.
Lo que aprendí
Construir EdgeGuard cambió mi forma de pensar sobre el análisis de código asistido por IA. La parte difícil no es lograr que un LLM entienda código: es controlar lo que el modelo tiene permitido asumir.
Si un helper desconocido se asume seguro, una vulnerabilidad puede desaparecer. Si cada función se envía a un LLM, el sistema se vuelve caro y difícil de escalar. Si el contexto específico del lenguaje se mezcla, el soporte multi-lenguaje se vuelve frágil.
La arquitectura terminó combinando tres enfoques:
Análisis estático para screening determinista rápido.
Investigación LLM para razonar sobre caminos de código complejos.
Verificación para convertir hipótesis en evidencia.
Ninguno de estos enfoques es perfecto por sí solo. Juntos, son mucho más interesantes.
Intenta romper tu propio código
EdgeGuard es una extensión open source de VS Code que sigue evolucionando. El proyecto está disponible aquí:
GitHub: https://github.com/phucphungbk/edgeguard
La idea detrás de EdgeGuard es deliberadamente simple:
No solo le pidas a la IA que escriba tu código. Pregúntale cómo podría fallar.
Si trabajas con aplicaciones sensibles a la seguridad, códigobase grandes o sistemas legacy, me encantaría saber cómo abordas este problema. ¿Cómo encuentras los casos límite? ¿Cómo lidias con los falsos negativos en el análisis automatizado? ¿Y cómo demuestras que un hallazgo de seguridad generado por IA es real?
Sigue explorando estos temas en el blog de DojoFullStack: la seguridad en el desarrollo con IA y los agentes de código son solo el comienzo de un área que está cambiando cómo construimos software.