OWASP LLM Top 10 en producción: cómo audité mi pipeline de agentes TypeScript contra los 10 riesgos y qué encontré A developer audited their TypeScript agent pipeline against the OWASP LLM Top 10 and found critical prompt injection vulnerabilities. The agent's MCP tool accepted external API responses without sanitization, allowing potential system prompt overwrites. The developer mitigated this by adding Zod schema validation and output escaping, and documented model-level risks as a trust boundary. Estaba revisando un system prompt de un agente MCP que había escrito tres semanas antes cuando me di cuenta de algo perturbador: el prompt aceptaba instrucciones de la respuesta de una tool externa. Sin sanitización. Sin validación. Sin ningún límite sobre qué podía hacer con esa salida. La tool llamaba a una API pública, recibía JSON, y ese JSON llegaba directo al contexto del modelo. Ahí fue cuando abrí el OWASP LLM Top 10 https://owasp.org/www-project-top-10-for-large-language-model-applications/ y paré de leerlo como lista de buenas prácticas para empezar a usarlo como lo que en realidad es: un framework de auditoría. Mi tesis es esta: la mayoría de los posts sobre OWASP LLM Top 10 te explican los diez riesgos. Ninguno te muestra cómo correrlos contra tu stack propio y qué encontrás cuando lo hacés en serio. Esa es la diferencia entre "leer el checklist" y "auditar el pipeline". Acá está lo segundo. Antes de entrar al checklist, el contexto: tengo un pipeline de agentes en TypeScript con tres capas que interactúan: Cada capa tiene una superficie de ataque diferente. Eso es lo que el OWASP LLM Top 10 me permitió ver con precisión quirúrgica. Este fue el hallazgo más gordo. Mi agente MCP recibía output de tools externas y lo incorporaba al contexto sin ninguna capa de sanitización. En un escenario adversarial, cualquier API que el agente consultara podría devolver texto diseñado para sobrescribir las instrucciones del system prompt. El patrón roto era este: // ❌ Patrón inseguro: output externo directo al contexto async function fetchContextAndInject url: string : Promise