A developer describes how they audit a TypeScript agent pipeline against the OWASP LLM AI Security & Governance “Top 10” framework, treating it as a checklist for their specific architecture rather than generic best practices. Their pipeline has three layers: structured system prompts, MCP-registered tools, and Cline as the client/orchestrator with access to the filesystem and terminal. In the audit, they report finding a major prompt-injection issue (LLM01) where external tool output is added to the model context without sanitization or validation. They add schema-based structural validation using Zod to reduce that attack surface. They also improve insecure output handling (LLM02) by escaping output before rendering to the DOM to mitigate potential XSS. For training data poisoning (LLM03), they state it is outside application control because it is a provider trust boundary. For model denial of service (LLM04), they add an iteration cap to limit repeated model calls. They add a CI step for dependency checks (LLM05), separate sensitive prompt/configuration (LLM06), review tool permissions for least privilege (LLM07), and require human confirmation for tools with irreversible effects (LLM08). They emphasize organizational process for overreliance (LLM09) and mitigate model theft (LLM10) by serving system prompts from an authenticated endpoint rather than exposing them in client code.
Developer details TypeScript agent audit against OWASP LLM Top 10 risks
A developer describes how they audit a TypeScript agent pipeline against the OWASP LLM AI Security & Governance “Top 10” framework, treating it as a checklist for their specific architecture rather th...
- The audit covers an MCP-based TypeScript agent pipeline with system prompts, registered tools, and a Cline client with filesystem/terminal access.
- The developer identifies prompt injection (LLM01) from external tool output being inserted into model context without sanitization or validation, and adds Zod-based structural validation.
- They implement output escaping/sanitization before rendering to reduce insecure output and potential XSS (LLM02).
- They add protections for denial of service (LLM04) by limiting agent loop iterations and log when the limit is reached.
- For tool execution risk (LLM08), they require human confirmation before running tools with destructive/irreversible side effects.
OWASP LLM Top 10 in Production: How I Audited My TypeScript Agent Pipeline Against All 10 Risks — and What I Found I was reviewing a system prompt for an MCP agent I'd written three weeks earlier when something hit me hard: the prompt was accepting instructions from the output of an external tool. No sanitization. No validation. No limits whatsoever on what it could do with that output. The tool called a public API, got back JSON, and that JSON landed directly in the model's context. That's when I opened the OWASP LLM Top 10 and stopped reading it like a list of best practices — and started using it for what it actually is: an audit framework. My thesis is simple: most posts about the OWASP LLM Top 10 explain the ten risks to you. None of them show you how to run them against your own stack and what you actually find when you do it seriously. That's the difference between "reading the checklist" and "auditing the pipeline." This post is the second thing. The Stack I Audited — and Why Context Matters Before getting into the checklist, some context: I have a TypeScript agent pipeline with three layers that interact with each other: Structured system prompts — instructions that define agent behavior, kept separate from user context MCP tools — tools registered following the Model Context Protocol, which the agent can call during a session Cline as the client — orchestrating execution inside the editor, with access to filesystem, terminal, and other tools Each layer has a different attack surface. That's exactly what the OWASP LLM Top 10 let me see with surgical precision. All 10 Risks: What I Found in Each One LLM01 — Prompt Injection This was the biggest finding. My MCP agent was receiving output from external tools and injecting it directly into context with zero sanitization layer. In an adversarial scenario, any API the agent queried could return text specifically crafted to overwrite the system prompt instructions. The broken pattern looked like this: // ❌ Insecure pattern: external output goes straight into context async function fetchContextAndInject(url: string): Promise<string> { const response = await fetch(url); const data = await response.json(); // data.content reaches the model context with no filtering whatsoever return data.content; } What I changed it to: // ✅ Structural validation before injecting into context import { z } from "zod"; const ExternalResponseSchema = z.object({ // Only accept fields with defined types — free-form strings flagged as suspicious title: z.string().max(200), summary: z.string().max(1000), // Anything not in the schema gets discarded }); async function fetchContextSafe(url: string): Promise<string> { const response = await fetch(url); const raw = await response.json(); // If the schema fails, the agent gets a structured error — not the raw payload const parsed = ExternalResponseSchema.parse(raw); return `Title: ${parsed.title}\nSummary: ${parsed.summary}`; } I used Zod — which was already in the stack for API validation — as the first line of defense. It's not a complete solution to prompt injection, but it reduces the structural attack surface. LLM02 — Insecure Output Handling The second problem: agent output was reaching the UI without escaping. In an agent that generates HTML or Markdown, that's potential XSS if the output gets rendered directly. I traced every place where model output touched the DOM and added explicit sanitization before any render. If the agent generates code, that code goes into a <pre> block with escaped characters — not into an innerHTML. LLM03 — Training Data Poisoning Here the OWASP LLM Top 10 points to risks in the base model, not the application. In my case the model is Claude via API — I don't control the fine-tuning or the dataset. My only action was to document this dependency explicitly: if Anthropic has a problem here, I have a problem here. No system prompt compensates for that. Honest limit: you can't audit this from the application layer. It's a dependency you take as a trust boundary. LLM04 — Model Denial of Service I checked whether I had rate limiting on the endpoints that trigger model calls. I didn't — at least not in the local testing context. In a production scenario this is critical: a badly designed loop or a tool that calls recursively can fire dozens of model requests in seconds. I added a simple iteration cap to the agent loop: // Iteration control to prevent infinite loops in the agent const MAX_ITERATIONS = 10; let iterations = 0; while (agentShouldContinue && iterations < MAX_ITERATIONS) { iterations++; const result = await runAgentStep(); agentShouldContinue = result.continueLoop; } if (iterations >= MAX_ITERATIONS) { // Explicit log — I want to know if this ever fires console.warn("[agent] Iteration limit reached — review loop"); } LLM05 — Supply Chain Vulnerabilities This risk made me look at two things: the npm packages I use to interact with the model API, and the dependencies of my MCP tools. With pnpm workspaces (something I covered in the monorepo with Railway post) you get lockfile visibility — but that's not the same as auditing. What I added: pnpm audit as an explicit CI step before deploying any agent. It doesn't eliminate the risk, but it makes it visible. LLM06 — Sensitive Information Disclosure This is where the second uncomfortable finding showed up: my system prompts contained configuration context that included names of internal tools, data structure details, and some system defaults. That context reaches the model — and if the model echoes it in its output, it's exposed. The rule I applied: nothing you wouldn't want to see in a public log should be in a system prompt without explicit confidentiality marking. And even that isn't a guarantee — it's mitigation. // Separate technical config from agent instructions const SYSTEM_PROMPT_PUBLIC = ` You are a development assistant. You can use available tools to answer technical questions. `; // This does NOT go into the system prompt — it lives in a separate config layer const AGENT_CONFIG_PRIVATE = { toolEndpoints: process.env.TOOL_ENDPOINTS, internalSchema: process.env.INTERNAL_SCHEMA, }; LLM07 — Plugin Design Flaws My MCP tools are essentially plugins. The risk here is that a tool has broader permissions than it actually needs. I reviewed each tool and applied least privilege: a tool that reads files doesn't need write access; a tool that queries an API doesn't need filesystem access. This connects directly to what I wrote about OAuth scope creep — the same audit pattern applies to an agent's tools. LLM08 — Excessive Agency This is the risk that concerns me most specifically with Cline. The agent has terminal access, can execute commands, can modify files. If the reasoning loop fails, it can cause real damage. What I implemented: "confirm before execute" mode for any tool with an irreversible side effect. It's not automatable — it requires deliberate human friction. And that friction is the entire point. // Explicit tool classification by impact type ToolImpact = "read-only" | "reversible" | "destructive"; const TOOL_IMPACT_MAP: Record<string, ToolImpact> = { readFile: "read-only", listDirectory: "read-only", writeFile: "reversible", deleteFile: "destructive", runCommand: "destructive", }; async function executeTool(toolName: string, args: unknown) { const impact = TOOL_IMPACT_MAP[toolName] ?? "destructive"; // safe fallback if (impact === "destructive") { // Pause and wait for human confirmation before executing await requireHumanApproval(toolName, args); } return runTool(toolName, args); } LLM09 — Overreliance This isn't a purely technical risk — it's organizational. The problem is trusting the agent's output without external validation. In my pipeline, any output going to production passes through a structural validation layer before it's used as input to another system. The model can be fine, the pipeline can be fine, and the output can still be wrong. This risk doesn't close with code. It closes with process and human review at critical nodes. LLM10 — Model Theft In my TypeScript agent context, this mainly applies to protecting system prompts. A well-crafted system prompt represents real work — and if it leaks, it can be replicated or used to bypass restrictions. What I implemented: system prompts don't live in frontend code. They're served from an authenticated endpoint, they're not logged in plain text, and they don't get exposed in the client bundle. What the OWASP LLM Top 10 Doesn't Tell You (Which Matters Just as Much) Here's what the list doesn't resolve on its own: It doesn't tell you the priority order for your stack. LLM01 (prompt injection) was critical in my case; LLM03 (training data poisoning) is irrelevant from the application layer. Without applying it against your concrete architecture, you don't know which one is urgent. It gives you no criteria for the trust boundary of the base model. If you use Claude, GPT-4, or any external API, LLM03 and part of LLM05 are dependencies you take as given. The framework names them, but the mitigation is out of your hands. It doesn't distinguish between runtime risks and design risks. LLM01 and LLM02 are problems you can detect and mitigate at runtime. LLM08 (excessive agency) is a design problem — if the agent has too many permissions, a runtime patch doesn't fix it. I have a post on OpenTelemetry in Next.js where I talk about traces that survive the edge. That kind of observability helps here too: if you can't see which tools the agent called and with what args, you can't audit LLM08 in production. Applied Checklist: The Real State of Each Risk in My Pipeline Risk State Found Action Taken LLM01 Prompt Injection ❌ Vulnerable Zod schema on external tool output LLM02 Insecure Output ⚠️ Partial Explicit escaping before render LLM03 Training Data 🔵 Out of scope Documented as trust boundary LLM04 Model DoS ⚠️ No limit Added max iterations + log LLM05 Supply Chain ⚠️ Invisible pnpm audit in CI LLM06 Info Disclosure ❌ Leaky prompts Separated config from system prompt LLM07 Plugin Flaws ⚠️ Partial Permission review per tool LLM08 Excessive Agency ⚠️ No friction Confirm before execute on destructive tools LLM09 Overreliance 🔵 Process Human validation at critical nodes LLM10 Model Theft ⚠️ Prompts exposed Prompts moved to authenticated endpoint ❌ = critical finding | ⚠️ = partial mitigation | 🔵 = outside application control FAQ Does the OWASP LLM Top 10 apply to agents built on Claude or GPT-4 via API? Yes, with nuance. LLM01, LLM02, LLM06, LLM07, LLM08, and LLM10 are application-layer risks — they apply regardless of which model you use. LLM03 (training data) and part of LLM05 are provider risks: if you use an external API, you take them as a trust boundary. The audit starts with the risks you can actually control. Is Zod enough to mitigate prompt injection? No. Zod validates the structure of external output before it reaches context — that reduces the surface area, but it doesn't eliminate the risk. A well-formed adversarial payload can pass schema validation. Zod is one layer, not a complete solution. Real mitigation combines schema validation, system prompt constraints, and human review at critical points. Is Cline safe to use in production as an agent orchestrator? Cline has access to the filesystem, terminal, and other tools with real effects. That's not inherently unsafe — it's the functionality that makes it useful. The risk (LLM08) is in the design: if the agent can execute destructive commands without human confirmation, the risk is real regardless of how well Cline is configured. My rule: any tool with an irreversible effect requires explicit approval. How often should you run this audit? Every time you change the agent's architecture: you add a new tool, change the system prompt, or modify how the agent consumes external outputs. It's not a one-time audit — it's a checklist that runs against every structural change. If you add observability (OpenTelemetry is one option), you can catch runtime anomalies between audits. Does the OWASP LLM Top 10 cover multi-agent risks or just single-agent? The current version (2025) primarily covers per-agent risk. In multi-agent architectures, LLM01's surface multiplies: each agent can become an injection vector for the others. The framework names the risk, but the mitigation detail for multi-agent pipelines is left to each team. Which risk should I tackle first if I have limited time? LLM01 (prompt injection) if your agent consumes external output — it's the most exploitable and the most overlooked. LLM08 (excessive agency) if the agent has access to tools with irreversible effects — it's the one that can do the most damage when something goes wrong. The rest depend on your specific stack, but these two are the absolute floor. The Difference Between Reading and Auditing My position is clear: the OWASP LLM Top 10 is not something you read and consider covered. It's something you bring into a review session with the architecture diagram open in front of you, and you ask — for each risk — exactly where in the pipeline that could fail. What I don't buy is the idea that "following best practices" is enough. Practices are abstract; the pipeline is concrete. In my case, LLM01 and LLM06 were real problems I wouldn't have found without doing the systematic audit exercise. I would have discovered them when someone motivated enough decided to exploit them. If you already have TypeScript agents with MCP tools or elaborate system prompts, do the exercise: open the OWASP LLM Top 10, open the architecture diagram, and ask risk by risk. The result will be more interesting than the list itself. Concrete next step: take the checklist from this table, replace the states with your own, and document the findings. An audit that isn't documented doesn't exist. Original source: OWASP LLM AI Security & Governance Checklist: https://owasp.org/www-project-top-10-for-large-language-model-applications/ This article was originally published on juanchi.dev
19 hours agoOWASP LLM Top 10 en producción: cómo audité mi pipeline de agentes TypeScript contra los 10 riesgos y qué encontré 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 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. El stack que audité y por qué importa el contexto Antes de entrar al checklist, el contexto: tengo un pipeline de agentes en TypeScript con tres capas que interactúan: System prompts estructurados — instrucciones que definen el comportamiento del agente, separadas del contexto de usuario MCP tools — tools registradas siguiendo el Model Context Protocol, que el agente puede llamar durante una sesión Cline como cliente — que orquesta la ejecución en el editor y tiene acceso a filesystem, terminal y otras herramientas 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. Los 10 riesgos: qué encontré en cada uno LLM01 — Prompt Injection 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<string> { const response = await fetch(url); const data = await response.json(); // data.content llega sin ningún filtro al contexto del modelo return data.content; } Lo que cambié: // ✅ Validación de estructura antes de incorporar al contexto import { z } from "zod"; const ExternalResponseSchema = z.object({ // Solo acepto campos con tipo definido — string libre marcado como sospechoso title: z.string().max(200), summary: z.string().max(1000), // Descarto cualquier campo que no esté en el schema }); async function fetchContextSafe(url: string): Promise<string> { const response = await fetch(url); const raw = await response.json(); // Si el schema falla, el agente recibe un error estructurado, no el payload crudo const parsed = ExternalResponseSchema.parse(raw); return `Título: ${parsed.title}\nResumen: ${parsed.summary}`; } Usé Zod — que ya tenía en el stack para validación de API — como primera línea. No es una solución completa al prompt injection, pero reduce la superficie de ataque estructural. LLM02 — Insecure Output Handling El segundo problema: el output del agente llegaba a la UI sin escaping. En un agente que genera HTML o Markdown, eso es XSS potencial si el output se renderiza directamente. Revisé dónde el output del modelo llegaba al DOM y agregué sanitización explícita antes de cualquier render. Si el agente genera código, ese código va a un bloque <pre> con escape de caracteres; no a un innerHTML. LLM03 — Training Data Poisoning Acá el OWASP LLM Top 10 apunta a riesgos del modelo base, no de la aplicación. En mi caso el modelo es Claude vía API — no controlo el fine-tuning ni el dataset. Mi única acción fue documentar esta dependencia explícitamente: si Anthropic tiene un problema acá, yo tengo un problema acá. Ningún sistema prompt lo compensa. Límite honesto: no podés auditar esto desde la aplicación. Es una dependencia que tomás como trust boundary. LLM04 — Model Denial of Service Revisé si tenía rate limiting en los endpoints que disparan llamadas al modelo. No lo tenía en el contexto de pruebas locales. En un escenario de producción esto es crítico: un loop mal diseñado o una tool que llama recursivamente puede generar decenas de requests al modelo en segundos. Agregué un límite simple de iteraciones al loop del agente: // Control de iteraciones para evitar loops infinitos en el agente const MAX_ITERATIONS = 10; let iterations = 0; while (agentShouldContinue && iterations < MAX_ITERATIONS) { iterations++; const result = await runAgentStep(); agentShouldContinue = result.continueLoop; } if (iterations >= MAX_ITERATIONS) { // Log explícito — quiero saber si esto se dispara console.warn("[agente] Límite de iteraciones alcanzado — revisar loop"); } LLM05 — Supply Chain Vulnerabilities Este riesgo me hizo revisar dos cosas: los paquetes npm que uso para interactuar con la API del modelo y las dependencias de mis MCP tools. Con pnpm workspaces (tema que ya cubrí en el post de monorepo con Railway) tenés visibilidad del lockfile, pero eso no es auditoría. Lo que agregué: pnpm audit como paso explícito en CI antes del deploy de cualquier agente. No elimina el riesgo, pero lo hace visible. LLM06 — Sensitive Information Disclosure Acá encontré el segundo hallazgo incómodo: en los system prompts tenía contexto de configuración que incluía nombres de tools internas, estructura de datos y algunos defaults del sistema. Ese contexto llega al modelo — y si el modelo lo repite en su output, lo expone. La regla que apliqué: nada que no quieras ver en un log público debería estar en un system prompt sin marcado explícito de confidencialidad. Y eso tampoco es garantía — es mitigación. // Separar configuración técnica de instrucciones del agente const SYSTEM_PROMPT_PUBLIC = ` Sos un asistente de desarrollo. Podés usar las herramientas disponibles para responder preguntas técnicas. `; // Esto NO va al system prompt — va a una capa de configuración separada const AGENT_CONFIG_PRIVATE = { toolEndpoints: process.env.TOOL_ENDPOINTS, internalSchema: process.env.INTERNAL_SCHEMA, }; LLM07 — Plugin Design Flaws Mis MCP tools son básicamente plugins. El riesgo acá es que una tool tenga permisos más amplios de lo necesario. Revisé cada tool y apliqué el principio de mínimo privilegio: una tool que lee archivos no necesita escribir; una tool que consulta una API no necesita acceso al filesystem. Esto conecta con lo que escribí sobre OAuth scope creep — el mismo patrón de auditoría aplica a las tools de un agente. LLM08 — Excessive Agency Este es el riesgo que más me preocupa en Cline específicamente. El agente tiene acceso a terminal, puede ejecutar comandos, puede modificar archivos. Si el loop de razonamiento falla, puede hacer daño real. Lo que implementé: modo "confirm before execute" para cualquier tool con efecto secundario irreversible. No es automatizable — requiere fricción humana deliberada. Y esa fricción es el punto. // Clasificación explícita de tools por impacto type ToolImpact = "read-only" | "reversible" | "destructive"; const TOOL_IMPACT_MAP: Record<string, ToolImpact> = { readFile: "read-only", listDirectory: "read-only", writeFile: "reversible", deleteFile: "destructive", runCommand: "destructive", }; async function executeTool(toolName: string, args: unknown) { const impact = TOOL_IMPACT_MAP[toolName] ?? "destructive"; // fallback seguro if (impact === "destructive") { // Pausa y espera confirmación humana antes de ejecutar await requireHumanApproval(toolName, args); } return runTool(toolName, args); } LLM09 — Overreliance No es un riesgo técnico puro — es organizacional. El problema es confiar en el output del agente sin validación externa. En mi pipeline, cualquier output que va a producción pasa por una capa de validación estructural antes de ser usado como input de otro sistema. El modelo puede estar seguro, el pipeline puede estar seguro, y el output puede seguir siendo incorrecto. Este riesgo no se cierra con código. Se cierra con proceso y revisión humana en los nodos críticos. LLM10 — Model Theft En mi contexto de agente TypeScript, esto aplica principalmente a la protección de los system prompts. Un system prompt elaborado representa trabajo real — y si se expone, puede ser replicado o usado para evadir restricciones. Lo que implementé: los system prompts no viven en el código del frontend. Se sirven desde un endpoint autenticado, no se loguean en texto plano y no se exponen en el bundle del cliente. Lo que el OWASP LLM Top 10 no te dice (y es igual de importante) Acá está lo que la lista no resuelve sola: No te dice el orden de prioridad para tu stack. LLM01 (prompt injection) fue crítico en mi caso; LLM03 (training data poisoning) es irrelevante desde la aplicación. Sin aplicarlo contra tu arquitectura concreta, no sabés cuál es urgente. No te da criterio para el trust boundary del modelo base. Si usás Claude, GPT-4 o cualquier API externa, LLM03 y parte de LLM05 son dependencias que tomás como dadas. El framework las nombra, pero la mitigación no está en tus manos. No distingue entre riesgos de runtime y riesgos de diseño. LLM01 y LLM02 son problemas que podés detectar y mitigar en runtime. LLM08 (excessive agency) es un problema de diseño — si el agente tiene demasiados permisos, un patch de runtime no lo arregla. Tengo un post sobre OpenTelemetry en Next.js donde hablo de traces que sobreviven el edge. Ese tipo de observabilidad también ayuda acá: si no podés ver qué tools llamó el agente y con qué args, no podés auditar LLM08 en producción. Checklist aplicado: el estado real de cada riesgo en mi pipeline Riesgo Estado encontrado Acción tomada LLM01 Prompt Injection ❌ Vulnerable Zod schema en output de tools externas LLM02 Insecure Output ⚠️ Parcial Escaping explícito antes de render LLM03 Training Data 🔵 Fuera de scope Documentado como trust boundary LLM04 Model DoS ⚠️ Sin límite Agregué max iterations + log LLM05 Supply Chain ⚠️ Invisible pnpm audit en CI LLM06 Info Disclosure ❌ Leaky prompts Separé config de system prompt LLM07 Plugin Flaws ⚠️ Parcial Revisión de permisos por tool LLM08 Excessive Agency ⚠️ Sin fricción Confirm before execute en tools destructivas LLM09 Overreliance 🔵 Proceso Validación humana en nodos críticos LLM10 Model Theft ⚠️ Prompts expuestos Prompts a endpoint autenticado ❌ = hallazgo crítico | ⚠️ = mitigación parcial | 🔵 = fuera del control de la aplicación FAQ ¿El OWASP LLM Top 10 aplica a agentes basados en Claude o GPT-4 vía API? Sí, con matices. LLM01, LLM02, LLM06, LLM07, LLM08 y LLM10 son riesgos de la aplicación — aplican sin importar qué modelo uses. LLM03 (training data) y parte de LLM05 son riesgos del proveedor: si usás una API externa, los tomás como trust boundary. La auditoría empieza por los riesgos que sí podés controlar. ¿Con Zod alcanza para mitigar prompt injection? No. Zod valida la estructura del output externo antes de que llegue al contexto — eso reduce la superficie, pero no elimina el riesgo. Un payload adversarial bien formado puede pasar la validación de schema. Zod es una capa, no una solución completa. La mitigación real combina schema validation, restricciones en el system prompt y revisión humana en puntos críticos. ¿Cline es seguro para usar en producción como orquestador de agentes? Cline tiene acceso a filesystem, terminal y otras herramientas con efecto real. Eso no es inherentemente inseguro — es la funcionalidad que lo hace útil. El riesgo (LLM08) está en el diseño: si el agente puede ejecutar comandos destructivos sin confirmación humana, el riesgo es real independientemente de qué tan bien esté configurado Cline. La regla que aplico: cualquier tool con efecto irreversible requiere aprobación explícita. ¿Cada cuánto hay que correr esta auditoría? Cada vez que cambiás la arquitectura del agente: agregás una tool nueva, cambiás el system prompt o modificás cómo el agente consume outputs externos. No es una auditoría de una sola vez — es un checklist que corre contra cada cambio estructural. Si agregás observabilidad (OpenTelemetry es una opción), podés detectar anomalías en runtime entre auditorías. ¿El OWASP LLM Top 10 cubre riesgos de multi-agente o solo agente único? La versión actual (2025) cubre principalmente el riesgo por agente. En arquitecturas multi-agente, la superficie de LLM01 se multiplica: cada agente puede ser un vector de inyección para los demás. El framework nombra el riesgo, pero el detalle de mitigación para pipelines multi-agente queda en manos de cada equipo. ¿Qué riesgo debería atacar primero si tengo tiempo limitado? LLM01 (prompt injection) si tu agente consume output externo — es el más explotable y el más ignorado. LLM08 (excessive agency) si el agente tiene acceso a herramientas con efecto irreversible — es el que más daño puede hacer en un fallo. Los demás dependen de tu stack, pero estos dos son el piso mínimo. Conclusión: la diferencia entre leer y auditar Mi postura es clara: el OWASP LLM Top 10 no sirve para leerlo y darlo por cubierto. Sirve para llevarlo a una sesión de revisión con el diagrama de arquitectura enfrente y preguntar, por cada riesgo, dónde exactamente en el pipeline eso puede fallar. Lo que no compro es la idea de que "seguir las buenas prácticas" alcanza. Las prácticas son abstractas; el pipeline es concreto. En mi caso, LLM01 y LLM06 eran problemas reales que no habría encontrado sin hacer el ejercicio de auditoría sistemática. Los habría descubierto cuando alguien con motivación los explotara. Si ya tenés agentes en TypeScript con MCP tools o system prompts elaborados, hacé el ejercicio: abrí el OWASP LLM Top 10, abrí el diagrama de arquitectura y preguntá riesgo por riesgo. El resultado va a ser más interesante que el listado. Próximo paso concreto: tomá el checklist de esta tabla, reemplazá los estados con los propios y publicá los hallazgos. La auditoría que no se documenta no existe. Fuente original: OWASP LLM AI Security & Governance Checklist: https://owasp.org/www-project-top-10-for-large-language-model-applications/ Este artículo fue publicado originalmente en juanchi.dev
19 hours ago
Israeli forces say they killed Al Jazeera journalist Ahmed Wishah in Gaza
Israeli military officials say a strike in Gaza killed Al Jazeera journalist Ahmed Wishah. NDTV reports that the Israeli...
Israeli strike kills Lebanese turtle conservationist Mona Khalil near Tyre
Lebanese turtle conservationist and environmental activist Mona Khalil dies after injuries from an Israeli strike near T...
Police raids target alleged illegal Sydney solariums, reporters describe operators’ tactics
Multiple outlets report details from police raids at an alleged illegal solarium business in Sydney, describing the cond...