flawopen.com/Incidents/microsoft-autogen-studio-autojack-agent-rce-june-2026
AutoJack : chaîne de RCE de recherche dans AutoGen Studio
Microsoft a trouvé une chaîne RCE locale via MCP dans le build de développement d’AutoGen Studio. Corrigée avant sortie, absente de PyPI.[1], [2]
Imaginez un laboratoire où un assistant lit les notes de visiteurs. Il peut entrer dans la salle de contrôle parce qu’il travaille dans le même bâtiment. L’accueil saute la vérification d’identité habituelle pour cette salle, et une note de visiteur peut choisir l’outil lancé. AutoJack a combiné ces raccourcis : un agent de navigation affichait du contenu non fiable, ce contenu atteignait le plan de contrôle MCP local d’AutoGen Studio et les paramètres fournis par l’appelant pouvaient entraîner le lancement d’un processus enfant. Il faut authentifier la salle de contrôle, retirer les paramètres de lancement des URL WebSocket et isoler l’assistant du poste du développeur. Microsoft indique que le correctif est arrivé sur la branche upstream avant toute version PyPI. La recherche porte sur du code prépublication, pas sur une version client concernée.[1]
Concepts Clés et Termes
AutoJack- Nom donné par Microsoft à une chaîne démontrée dans une version de développement d’AutoGen Studio. Le rapport précise que la route MCP concernée a été corrigée avant son inclusion dans un paquet PyPI publié.[1], [2]
Loopback / localhost- Interface réseau permettant d’atteindre des services sur le même hôte. Elle limite l’accès depuis le réseau externe, mais n’isole pas les processus locaux, comme le navigateur d’un agent, des autres services de l’hôte.[1]
Validation Origin du WebSocket- Vérification côté serveur de l’en-tête Origin lors du handshake WebSocket. Microsoft a constaté que, dans le flux d’agent testé, cette vérification seule n’empêchait pas la page affichée d’atteindre le service MCP local.[1], [3]
StdioServerParams- Configuration stdio MCP d’AutoGen, comprenant le programme et les arguments qui lancent un processus serveur. La route décrite décodait ces paramètres depuis une valeur de l’URL WebSocket.[1], [2], [5]
Confused deputy- Un composant privilégié est amené à utiliser ses propres droits pour une partie non fiable. Ici, l’agent de navigation et le service local Studio reliaient le contenu d’une page au lancement de processus sur l’hôte.[1]
Correspondances de référentiels
- Référence CWE pour la faiblesse décrite dans ce guide : CWE-78 CWE-306 CWE-1385
- OWASP GenAI 2025 — LLM06:2025 Agence excessive
Chronologie de l'Incident
Microsoft a publié la recherche AutoJack et ses mesures de protection. Elle décrit une démonstration locale contrôlée, pas une attaque confirmée contre des clients.[1]
Déroulement de l'Attaque Étape par Étape
L’agent doit consulter du contenu non fiable
Un prompt, une page récupérée ou une autre entrée non fiable amène un agent de navigation AutoGen à afficher une page contrôlée par un attaquant sur le poste qui exécute AutoGen Studio.[1]
Code Source : Vulnérable vs Sécurisé
L’exemple vulnérable analyse des paramètres de lancement contrôlés par l’appelant, mais ne démarre volontairement aucun processus. Le correctif upstream a retiré ces paramètres de la requête WebSocket, les a placés dans une session serveur à usage unique et a rétabli l’authentification des routes MCP. Ce modèle défensif ajoute expiration, limite de taille, verrouillage concurrent et liste d’exécutables autorisés ; remplacez le nom d’exemple par les binaires MCP approuvés. Il ne remplace ni la validation Origin ni l’isolation du système d’exploitation.[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 route de développement faisait confiance à la configuration fournie dans l’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 doit provenir d’un middleware vérifié, jamais des données de la requête.
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]Liste de Contrôle de Sécurité pour l'Ingénierie
- ✓Exigez authentification et autorisation sur toutes les routes du plan de contrôle MCP, y compris les handshakes WebSocket ; testez chaque mode d’authentification configuré sur ces routes.[1], [2], [4]
- ✓N’acceptez jamais de configuration de lancement de processus dans une URL WebSocket ou une autre entrée contrôlée par le navigateur ; enregistrez-la via une requête authentifiée et liez-la à une session côté serveur courte et à usage unique.[2]
- ✓Faites expirer les sessions en attente, limitez leur nombre, consommez chaque session de façon atomique et rejetez les identifiants inconnus, expirés ou rejoués.[2]
- ✓Autorisez uniquement des exécutables MCP approuvés et des schémas d’arguments fixes ; ne laissez pas la sortie du modèle ou le contenu d’une page choisir des programmes arbitraires.[1], [5]
- ✓Séparez les agents de navigation qui affichent des pages non fiables des plans de contrôle locaux privilégiés ; bloquez l’accès loopback depuis le sandbox du navigateur si possible.[1], [3]
- ✓Exécutez l’agent et Studio avec une identité à faibles privilèges ou dans une VM/un conteneur jetable, et déclenchez une alerte sur les processus enfants inattendus des runtimes d’agents.[1]
- ✓Pour les builds source d’AutoGen Studio, utilisez une révision égale ou postérieure à b047730. Microsoft précise que la route concernée ne figurait pas dans le paquet PyPI alors publié ; vérifiez l’artefact exact que vous déployez.[1], [2]
Sources
- Microsoft Security Blog — AutoJack : comment une page peut exécuter du code sur l’hôte d’un agent IA
- Commit b047730 de Microsoft AutoGen — sécurisation du point de terminaison MCP WebSocket
- CWE-1385 : absence de validation Origin dans les WebSockets
- CWE-306 : absence d’authentification pour une fonction critique
- CWE-78 : neutralisation incorrecte d’éléments spéciaux dans une commande système