flawopen.com/Incidents/microsoft-autogen-studio-autojack-agent-rce-june-2026
AutoJack: cadena de RCE de investigación en AutoGen Studio
Microsoft halló RCE local vía MCP en un build de desarrollo de AutoGen Studio. Se corrigió antes del lanzamiento y no llegó a PyPI.[1], [2]
Imagina un laboratorio donde un asistente lee notas de visitantes. El asistente puede entrar en la sala de control porque trabaja en el mismo edificio. La recepción omite la comprobación de identidad habitual para esa sala, y una nota de un visitante puede elegir qué herramienta se inicia. AutoJack encadenó esos atajos: un agente de navegación mostró contenido no confiable, ese contenido llegó al plano de control MCP local de AutoGen Studio y la configuración aportada por quien llamaba podía provocar un proceso hijo. La lección es autenticar la sala de control, sacar la configuración de inicio de las URL de WebSocket y aislar al asistente del equipo del desarrollador. Microsoft afirma que se corrigió en la rama upstream antes de una versión de PyPI. La investigación trata de código previo al lanzamiento, no de una versión de clientes afectada.[1]
Conceptos Clave y Términos
AutoJack- Nombre de Microsoft para una cadena demostrada en una compilación de desarrollo de AutoGen Studio. El informe dice que la ruta MCP afectada se corrigió antes de aparecer en un paquete PyPI publicado.[1], [2]
Loopback / localhost- Interfaz de red que accede a servicios del mismo host. Limita el acceso desde redes externas, pero no aísla procesos locales, como el navegador de un agente, de otros servicios del host.[1]
Validación de Origin en WebSocket- Comprobación del servidor sobre el encabezado Origin durante el handshake de WebSocket. Microsoft observó que, en el flujo de agente probado, esa comprobación por sí sola no impedía que la página mostrada llegara al servicio MCP local.[1], [3]
StdioServerParams- Configuración stdio de MCP en AutoGen, incluido el programa y sus argumentos para iniciar un proceso servidor. La ruta descrita decodificaba estos datos desde un parámetro de la URL WebSocket.[1], [2], [5]
Confused deputy- Un componente privilegiado es inducido a usar su propia autoridad en beneficio de una parte no confiable. Aquí, el agente de navegación y el servicio local de Studio conectaban el contenido web con la creación de procesos en el host.[1]
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-78 CWE-306 CWE-1385
- OWASP GenAI 2025 — LLM06:2025 Agencia excesiva
Cronología del Incidente
Microsoft publicó la investigación AutoJack y sus medidas de mitigación. Describe una demostración local controlada, no un ataque confirmado contra clientes.[1]
Flujo de Ataque Paso a Paso
Se pide al agente que navegue por contenido no confiable
Un prompt, una página recuperada u otra entrada no confiable hace que un agente de navegación de AutoGen muestre una página controlada por un atacante en el mismo equipo que ejecuta AutoGen Studio.[1]
Código Fuente: Vulnerable vs. Seguro
El ejemplo vulnerable analiza parámetros de inicio controlados por quien llama, pero deliberadamente no inicia procesos. La corrección upstream sacó esos parámetros de la consulta WebSocket, los guardó en una sesión server-side de un solo uso y restauró la autenticación en las rutas MCP. Este patrón defensivo añade caducidad, límite de tamaño, bloqueo concurrente y una lista permitida de ejecutables; sustituya el nombre de ejemplo por los binarios MCP aprobados. No sustituye la validación de Origin ni el aislamiento del sistema operativo.[1], [2]
import base64
import json
from dataclasses import dataclass
@dataclass(frozen=True)
class StdioServerParams:
command: str
args: tuple[str, ...]
def params_from_websocket_query(query: dict[str, str]) -> StdioServerParams:
# La ruta de desarrollo confiaba en la configuración proporcionada en la URL.
encoded = query["server_params"]
decoded = base64.b64decode(encoded)
return StdioServerParams(**json.loads(decoded))from dataclasses import dataclass
from threading import Lock
from time import monotonic
from uuid import uuid4
@dataclass(frozen=True)
class StdioServerParams:
command: str
args: tuple[str, ...]
SESSION_TTL = 30.0
MAX_PENDING = 256
ALLOWED_COMMANDS = {"approved-mcp-server"}
pending: dict[str, tuple[float, StdioServerParams]] = {}
pending_lock = Lock()
def register_params(params: StdioServerParams, authenticated: bool) -> str:
# authenticated debe proceder de middleware verificado, nunca de los datos de la solicitud.
if not authenticated:
raise PermissionError("MCP control-plane authentication required")
if params.command not in ALLOWED_COMMANDS:
raise ValueError("unapproved MCP server executable")
now = monotonic()
with pending_lock:
for key, (expires, _) in list(pending.items()):
if expires <= now:
pending.pop(key, None)
if len(pending) >= MAX_PENDING:
raise RuntimeError("pending MCP session limit reached")
session_id = str(uuid4())
pending[session_id] = (now + SESSION_TTL, params)
return session_id
def consume_params(session_id: str, authenticated: bool) -> StdioServerParams:
if not authenticated:
raise PermissionError("MCP control-plane authentication required")
with pending_lock:
entry = pending.pop(session_id, None)
if entry is None or entry[0] <= monotonic():
raise ValueError("unknown or expired MCP session")
return entry[1]Lista de Verificación de Seguridad para Ingeniería
- ✓Exige autenticación y autorización en todas las rutas del plano de control MCP, incluidos los handshakes WebSocket; prueba cada modo de autenticación configurado en esas rutas.[1], [2], [4]
- ✓No aceptes configuración para iniciar procesos en una URL WebSocket ni en otra entrada controlada por el navegador; regístrala mediante una solicitud autenticada y vincúlala a una sesión server-side breve y de un solo uso.[2]
- ✓Haz caducar las sesiones pendientes, limita su cantidad, consume cada sesión de forma atómica y rechaza identificadores desconocidos, vencidos o reutilizados.[2]
- ✓Permite solo ejecutables MCP aprobados y esquemas de argumentos fijos; no dejes que la salida del modelo o el contenido web seleccione programas arbitrarios.[1], [5]
- ✓Mantén los agentes que muestran páginas no confiables separados de planos de control locales privilegiados; bloquea el acceso loopback desde el sandbox del navegador cuando sea posible.[1], [3]
- ✓Ejecuta el agente y Studio con una identidad de pocos privilegios o una VM/contenedor desechable, y alerta sobre procesos hijos inesperados de runtimes de agentes.[1]
- ✓Para compilar AutoGen Studio desde el código fuente, usa una revisión igual o posterior a b047730. Microsoft dice que la ruta afectada no estaba en el paquete PyPI disponible entonces; verifica el artefacto exacto que despliegas.[1], [2]
Fuentes
- Microsoft Security Blog — AutoJack: cómo una página puede ejecutar código en el host de un agente de IA
- Commit b047730 de Microsoft AutoGen — refuerzo del endpoint MCP WebSocket
- CWE-1385: falta de validación de Origin en WebSockets
- CWE-306: falta de autenticación para una función crítica
- CWE-78: neutralización incorrecta de caracteres especiales en comandos del sistema