Seguridad en MCP: integra herramientas de forma segura
Qué cubre este artículo sobre seguridad en MCP
- Cómo integrar herramientas MCP de forma segura para agentes de IA.
- Cómo implementar validación de herramientas y protección contra inyecciones.
- Cómo usar sandboxing para herramientas críticas.
- Ejemplos prácticos de integración segura de herramientas.
- Mejores prácticas para seguridad y minimización de riesgos.
Introducción: seguridad en MCP explicada
La seguridad en MCP significa que tus herramientas están protegidas contra mal uso, inyecciones y accesos no autorizados. Un agente no debería poder invocar herramientas arbitrarias, enviar parámetros sin restricción ni exfiltrar datos sensibles.
Este artículo está dirigido a quienes desean integrar herramientas MCP de forma segura. Los conceptos fundamentales los encontrarás en MCP y seguridad de agentes.
Por qué necesito seguridad en MCP
Imagina que tu agente tiene una herramienta llamada “execute_command”. Sin seguridad podría ejecutar rm -rf /. Con seguridad solo puede ejecutar comandos permitidos, con parámetros permitidos, y todas las acciones quedan registradas. La seguridad en MCP previene el mal uso.
Seguridad en MCP en resumen
MCP-Tool + Seguridad = Validación de entrada, permisos, sandboxing, registro de auditoría. El agente solo puede ejecutar herramientas permitidas, parámetros permitidos, acciones permitidas.
La idea central es prevenir el mal uso mediante validación y control.
A quién va dirigido este artículo
- Conscientes de seguridad que quieren asegurar agentes.
- Desarrolladores que construyen herramientas seguras.
- Administradores que implementan control de acceso.
- DevOps que despliegan agentes de forma segura.
Términos importantes
- MCP - Model Context Protocol. Útil para: integración de herramientas.
- Permisos de herramientas - Control de acceso. Útil para: seguridad.
- Prompt Injection - Ataques. Útil para: identificar riesgos.
- Sandboxing - Aislamiento. Útil para: herramientas críticas.
- Audit Logging - Registro de auditoría. Útil para: trazabilidad.
Capas de seguridad
Solicitud del agente
│
▼
1. Validación de entrada
├─ Verificar tipos de parámetros
├─ Verificar rangos de valores
└─ Detectar patrones de inyección
│
▼
2. Permisos
├─ ¿Herramienta permitida?
├─ ¿Acción permitida?
└─ ¿Scope permitido?
│
▼
3. Sandboxing (para herramientas críticas)
├─ Entorno aislado
├─ Sin accesos del sistema
└─ Límites de tiempo de espera
│
▼
4. Registro de auditoría
├─ ¿Quién? ¿Qué? ¿Cuándo?
├─ ¿Éxito? ¿Error?
└─ Alertas ante anomalías
│
▼
Ejecución de herramienta
Ejemplo práctico 1: validación de entrada
import re
from typing import Any
class SecureTool:
"""Herramienta segura con validación de entrada"""
def validate_input(self, param_name: str, value: Any, param_type: type):
"""Validar entrada"""
# Verificar tipo
if not isinstance(value, param_type):
raise ValidationError(f"{param_name} must be {param_type.__name__}")
# Verificar patrones de inyección
if isinstance(value, str):
dangerous_patterns = [
r"rm\s+-rf", r"sudo", r"eval\(", r"exec\(",
r"__import__", r"subprocess", r"os\.system"
]
for pattern in dangerous_patterns:
if re.search(pattern, value, re.IGNORECASE):
raise SecurityError(f"Dangerous pattern detected: {pattern}")
return True
def safe_execute(self, command: str):
"""Ejecución segura"""
# Validación
self.validate_input("command", command, str)
# Solo comandos permitidos
allowed_commands = ["ls", "pwd", "cat", "grep", "find"]
cmd = command.split()[0]
if cmd not in allowed_commands:
raise PermissionError(f"Command '{cmd}' not allowed")
# Ejecutar
import subprocess
result = subprocess.run(
command.split(),
capture_output=True,
text=True,
timeout=10
)
return result.stdout
Ejemplo práctico 2: sandboxing
import docker
class SandboxedTool:
"""Herramienta en sandbox"""
def __init__(self):
self.client = docker.from_env()
def execute_in_sandbox(self, code: str):
"""Ejecutar código en sandbox"""
# Contenedor Docker para aislamiento
container = self.client.containers.run(
image="python:3.11-slim",
command=f"python -c '{code}'",
remove=True,
network_disabled=True, # Sin red
mem_limit="128m", # Límite de memoria
cpu_period=100000,
cpu_quota=50000, # Límite de CPU
security_opt=["no-new-privileges"],
cap_drop=["ALL"] # Sin capabilities
)
return container.decode("utf-8")
Ejemplo práctico 3: protección contra inyecciones
class InjectionProtectedTool:
"""Herramienta con protección contra inyecciones"""
def sanitize_input(self, user_input: str) -> str:
"""Desinfectar entrada"""
# Remover/escapar caracteres peligrosos
sanitized = user_input
sanitized = sanitized.replace(";", "")
sanitized = sanitized.replace("|", "")
sanitized = sanitized.replace("&", "")
sanitized = sanitized.replace("`", "")
sanitized = sanitized.replace("$(", "")
sanitized = sanitized.replace("${", "")
return sanitized
def safe_query(self, table: str, filters: dict):
"""Consulta de base de datos segura"""
# Validar nombre de tabla (sin SQL injection)
if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', table):
raise ValidationError("Invalid table name")
# Desinfectar filtros
sanitized_filters = {}
for key, value in filters.items():
sanitized_filters[key] = self.sanitize_input(str(value))
# Consulta parametrizada
return self.db.query(table, sanitized_filters)
Ejemplo práctico 4: registro de auditoría
import logging
from datetime import datetime
class AuditedTool:
"""Herramienta con registro de auditoría"""
def __init__(self):
self.logger = logging.getLogger("mcp_tool")
def log_tool_call(self, tool_name, params, result, status):
"""Registrar invocación de herramienta"""
self.logger.info({
"timestamp": datetime.now().isoformat(),
"tool": tool_name,
"params": params,
"result": str(result)[:1000], # Truncar para log
"status": status
})
def execute_with_audit(self, tool_name, params):
"""Ejecutar herramienta con auditoría"""
try:
result = self.execute(tool_name, params)
self.log_tool_call(tool_name, params, result, "success")
return result
except Exception as e:
self.log_tool_call(tool_name, params, str(e), "error")
raise
Notas sobre seguridad
- Validación de entrada: validar todos los parámetros (tipo, formato, rango).
- Protección contra inyecciones: prevenir SQL injection, command injection, code injection.
- Sandboxing: para herramientas críticas (ejecución de código) usa sandboxing. Ver Sandboxing.
- Permisos: aplicar least privilege en todas las herramientas. Ver Permisos de herramientas.
- Auditoría: registrar todas las invocaciones de herramientas. Ver Audit Logging.
- Rate-limiting: establecer límites de velocidad para APIs externas.
Errores comunes a evitar
- Sin validación de entrada: El agente puede enviar parámetros arbitrarios. Siempre valida.
- Concatenación de strings: Para SQL y comandos, usa queries parametrizadas, nunca concatenación.
- Sin sandboxing: Las herramientas críticas (ejecución de código) sin aislamiento son peligrosas.
- Demasiados permisos: El agente no debería tener acceso a todas las herramientas.
- Sin auditoría: Sin logs, no sabes qué hizo el agente.
Enlaces relacionados
- MCP - Model Context Protocol.
- Permisos en MCP - Control de acceso.
- Herramientas MCP personalizadas - Construcción de tools.
- Permisos de herramientas - Permisos.
- Sandboxing - Aislamiento.
- Prompt Injection - Ataques.
- Auditoría - Registro de eventos.
Puntos clave:
- Seguridad en MCP: validación de entrada, permisos, sandboxing, auditoría.
- Protección contra inyecciones: previene SQL, Command e Code Injection.
- Sandboxing para herramientas críticas (ejecución de código).
- Principio de menor privilegio en todas las herramientas.
- Log de auditoría para trazabilidad.
FAQ
¿Qué es la seguridad en MCP?
¿Cuáles son los riesgos?
¿Cómo protejo mis herramientas?
¿Qué es sandboxing?
¿Cómo evito inyecciones?
¿Por qué log de auditoría?
¿Qué es Prompt Injection?
¿Cuáles son las mejores prácticas?
Referencias y lecturas recomendadas
- MCP - Model Context Protocol.
- OWASP - Prácticas de seguridad.
- Prompt Injection - Entender los ataques.


