# AX-SYS-26: Nunca interpoles la entrada del agente en comandos o consultas

> Tools and capabilities · intermediate · AX-SYS-26

Trata cada argumento que envía un agente como entrada no confiable, y pásalo a shells, bases de datos e intérpretes solo como parámetro, nunca como parte de una cadena que construyes y ejecutas.

## Por qué

Los argumentos de una herramienta los escribe un modelo, y el contexto del modelo puede contener texto que un atacante dejó en una página web, un correo o un documento. Lo que llega a tu herramienta puede ser hostil aunque ni el agente ni su usuario lo sean. OWASP incluye la inyección de comandos como MCP05 en su MCP Top 10: ocurre cuando la petición de un agente se convierte en un comando del sistema, un script, una consulta o un fragmento de código construido con entrada no confiable y sin validar. Las defensas son antiguas y conocidas, y se aplican sin cambios. La guía de OWASP es no usar nunca `shell=True`, `eval()`, `exec()` ni comandos construidos con cadenas, ejecutar con parámetros estructurados, validar la salida del agente contra un esquema antes de actuar y usar SQL y APIs parametrizadas. Su hoja de referencia sobre inyección de comandos pone primero evitar los comandos del sistema (una función de biblioteca no se puede convencer de hacer otra cosa) y después la parametrización junto con la validación de entradas. La especificación de MCP deja clara la parte del servidor: los servidores DEBEN validar todas las entradas de las herramientas y sanear sus salidas. El esquema de entrada de tu herramienta es el primer filtro; la ejecución parametrizada es la que resiste cuando el esquema admite una cadena.

## Haz

Valida los argumentos contra el esquema de la herramienta y pásalos a comandos y consultas como parámetros separados.

## No hagas

Construir un comando de shell, una sentencia SQL o una cadena para `eval` concatenando lo que envió el agente.

## Artefacto

```python
# Mal: la ruta del agente pasa a formar parte de la línea de comandos
os.system(f"tar -czf backup.tgz {args['path']}")
cursor.execute(f"SELECT * FROM orders WHERE customer = '{args['customer']}'")

# Bien: los argumentos siguen siendo datos
subprocess.run(["tar", "-czf", "backup.tgz", "--", args["path"]], check=True)
cursor.execute("SELECT * FROM orders WHERE customer = %s", (args["customer"],))
```

## Fuentes

1. [MCP Specification 2026-07-28: Tools (Security Considerations)](https://modelcontextprotocol.io/specification/2026-07-28/server/tools): Servers MUST validate all tool inputs, implement proper access controls, rate limit tool invocations, and sanitize tool outputs
2. [OWASP MCP Top 10 (MCP05:2025 Command Injection & Execution)](https://owasp.github.io/www-project-mcp-top-10/2025/MCP05-2025%E2%80%93Command-Injection&Execution): Command injection occurs when an AI agent constructs and executes system commands, shell scripts, API calls, or code snippets using untrusted input without proper validation or sanitization. Never use shell=True, eval(), exec(), or string-built commands; always execute with structured parameters, validate agent output against schemas before execution, and use parameterized SQL/APIs, never interpolating input
3. [OWASP Cheat Sheet Series: OS Command Injection Defense](https://cheatsheetseries.owasp.org/cheatsheets/OS_Command_Injection_Defense_Cheat_Sheet.html): The primary defense is to avoid calling OS commands directly, since built-in library functions cannot be manipulated to perform other tasks; where that is not possible, use parameterization, structured mechanisms that automatically enforce the separation between data and command, together with input validation

---
Source: Agent Experience Principles (axprinciples.com)