1. Executive summary
Microsoft Defender Security Research disclosed an exploit chain ("AutoJack") in AutoGen Studio, the open-source prototyping UI for Microsoft Research's AutoGen multi-agent framework. The chain lets an attacker deliver arbitrary code execution on the host running the agent by combining three weaknesses in the local Model Context Protocol (MCP) WebSocket control plane: a localhost-only Origin allowlist that an on-host agent trivially satisfies, an authentication middleware that explicitly skips MCP paths, and a server_params query parameter that is base64-decoded and handed verbatim to stdio_client() for process spawning. No CVE, CVSS score, or CISA-KEV state has been published for this issue; severity is therefore unconfirmed in this advisory. The vulnerable code was fixed in upstream commit b047730 and was never shipped to PyPI — pip install autogenstudio (currently 0.4.2.2) does not contain the affected route. Exposure is limited to developers who built AutoGen Studio from the main GitHub branch during the window between the MCP plugin landing and the hardening commit. For EMEA financial services, the risk is concentrated in any developer workstation, sandbox, or CI runner where AutoGen Studio is built from source and a browsing or code-execution agent is permitted to render untrusted web content on the same host.
2. Regulatory framing
| Article | Trigger (fact in this item) | Practical impact |
|---|---|---|
| DORA Art. 28 — ICT third-party risk — general principles | AutoGen Studio is an ICT third-party component (open-source framework) used in development environments that support ICT systems within scope of DORA. | Treat AutoGen Studio as an in-scope ICT third-party for risk assessment; document its use, the build source (PyPI vs. main), and the agent capabilities enabled. |
| DORA Art. 29 — preliminary assessment of ICT concentration risk | Widespread internal use of a single agent framework (AutoGen) across developer estates creates concentration risk against a common vulnerability class (localhost control-plane abuse). | Include AutoGen Studio / AutoGen in concentration-risk assessments; record the dependency and the version-pinning policy. |
| NIS2 Art. 21(2)(d) — supply chain security measures | AutoGen Studio is a third-party AI/agent component in the software supply chain; the disclosed chain demonstrates a concrete supply-chain attack vector against developer hosts. | Apply supply-chain security controls: pin to a known-good build (commit b047730 or later, or PyPI 0.4.2.2), verify provenance, and restrict agent capabilities on hosts handling in-scope services. |
| UK NIS 2018 — OES/RDSP duties | An OES/RDSP operator running AutoGen Studio on a workstation or server that supports an essential service. | Apply the operator's existing secure-development and third-party controls to any AutoGen Studio deployment; ensure incident-handling processes cover developer-host compromise originating from agent-driven RCE. |
DORA Art. 17, Art. 18, Art. 19, Art. 24, and Art. 30 are not directly engaged by the facts of this item and are not cited.
3. Technical analysis & attack chain
The chain is composed of three independent weaknesses in the AutoGen Studio MCP WebSocket surface. Each is a reasonable shortcut in a research-grade prototype; chained together they form a confused-deputy RCE primitive.
Weakness 1 — CWE-1385 (Missing Origin Validation in WebSockets). The MCP WebSocket accepts connections only when the Origin header is http://127.0.0.1 or http://localhost. This is the correct control against a human user opening a tab to evil.com, but it is the wrong control for an agent. Any headless browser owned by an AutoGen agent running on the same workstation inherits the localhost identity; the Origin of any JavaScript it executes is the page it navigated to, and the WebSocket call it then makes carries an Origin that satisfies the allowlist.
Weakness 2 — CWE-306 (Missing Authentication for Critical Function). AutoGen Studio supports four auth modes (none, github, msal, firebase) wired into a single AuthMiddleware that runs ahead of FastAPI dispatch. The middleware contains an early-return for WebSocket-style paths:
if request.url.path.startswith("/api/ws") or request.url.path.startswith("/api/mcp"):
return await call_next(request)
The intent was for the WebSocket handler to enforce auth itself at accept time. The MCP route never picked up that responsibility. The resulting matrix is:
| Auth configuration | REST API protected? | /api/mcp/ws/* protected? |
|---|---|---|
none |
No | No |
github |
Yes | No |
msal |
Yes | No |
firebase |
Yes | No |
Enabling auth in config.yaml does not close this hole on its own.
Weakness 3 — CWE-78 (OS Command Injection via StdioServerParams). The MCP WebSocket route reads a server_params query parameter, base64-decodes it, JSON-parses it into StdioServerParams, and passes it to stdio_client(...):
@router.websocket("/ws/{session_id}")
async def mcp_websocket(websocket: WebSocket, session_id: str):
encoded = websocket.query_params.get("server_params")
decoded = base64.b64decode(encoded)
params = StdioServerParams(**json.loads(decoded))
await create_mcp_session(bridge, params, session_id)
StdioServerParams.command and StdioServerParams.args are passed to stdio_client, which spawns an MCP "server" process. There is no allowlist requiring the executable to be an MCP-speaking binary; the same plumbing happily spawns calc.exe, powershell.exe -enc …, or bash -c '…'.
End-to-end attack chain (confirmed by Microsoft in a controlled local PoC)
- A developer runs AutoGen Studio on
localhost:8081(default port) and opens a "Web Content Summarizer" agent (or any agent with browsing + MCP capabilities) on the same machine. - An attacker plants a malicious comment on a legitimate news site, or the user is prompted (directly, via prompt injection in earlier content, or via a URL field) to summarize an attacker-controlled URL.
- The agent's browsing tool (
MultimodalWebSurfer,fetch_webpage_tool, any Playwright-backed surfer, or a code-execution tool that runsrequests/websockets) navigates the headless browser to the attacker's page. - The page's JavaScript opens
ws://localhost:8081/api/mcp/ws/<id>?server_params=<base64>. The browser is on the same machine, so theOriginis acceptable; the auth middleware short-circuits/api/mcp/*, so no token is required. - AutoGen Studio decodes the payload and runs
calc.exe(or anything else) under the developer's account. The parent process is the AutoGen Studio process, not the browser and not the headless Chromium.
A minimal payload:
{
"type": "StdioServerParams",
"command": "calc.exe",
"args": [],
"env": { "pwned": "true" }
}
Base64-encoded into a query string, the full reach-out is:
ws://localhost:8081/api/mcp/ws/?server_params=<base64>
Persistence, C2, lateral movement, exfiltration. The source does not describe persistence, C2, lateral movement, or exfiltration behaviour beyond the initial process spawn. The chain is a confused-deputy RCE primitive; whatever the attacker chooses to launch inherits the developer's account and the developer's network position. Treat any successful AutoJack execution as a developer-host compromise and apply the standard developer-host IR playbook (credential rotation, autostart review, lateral-movement hunt).
Exposure scope (confirmed). Microsoft confirmed by downloading autogenstudio 0.4.2.2 and inspecting its contents: the package does not include autogenstudio/web/routes/mcp.py, the FastAPI application in app.py does not mount an /api/mcp router, and a recursive search across all 55 Python files found no matches for StdioServerParams or /api/mcp. Users who pip install autogenstudio today get a build that does not contain the MCP WebSocket attack surface at all. Exposure was limited to developers who built from main between the MCP plugin landing and commit b047730. pyproject.toml on main is at version 0.7.2.
Unconfirmed / single-sourced claims. The behavioural-detection guidance (parent-process heuristics, WebSocket upgrade logging, browser-automation domain filtering) is sourced from Microsoft's own Defender / Defender for Cloud / Entra product documentation and is presented as best-practice rather than as observed-in-the-wild telemetry from this campaign. Treat it as guidance, not as confirmed detection of an active incident.
4. Mitigation & containment
P1 — within 24 hours
- Confirm build provenance. For every host running AutoGen Studio, determine whether it was installed via
pip install autogenstudio(currently0.4.2.2) or built from themainGitHub branch. PyPI installs are not exposed to this specific chain;main-branch builds require immediate action. - If built from
main, upgrade to a build at or after commitb047730. Verify by inspecting the working tree: the WebSocket handler must no longer readserver_paramsfrom the URL, and the middleware skip-list must no longer include/api/mcp. - Bind to loopback only and firewall the port. Force AutoGen Studio to bind
127.0.0.1and add a host firewall rule blocking all non-loopback traffic to TCP8081(default). On Windows:New-NetFirewallRule -DisplayName "Block AutoGen Studio 8081" -Direction Inbound -LocalPort 8081 -RemoteAddress Any -Action Block(with an exception for127.0.0.1if required by the framework). On Linux: anft/iptablesrule denying inbound to8081from non-lo. - Place behind an authenticated reverse proxy that enforces auth on all paths, including any future WebSocket or
/api/*routes. Do not rely on framework auth modes alone for control-plane endpoints.
P2 — within 72 hours
- Run AutoGen Studio under a low-privilege account in a sandboxed user profile or container so that any future agent-driven RCE is contained to a dev profile, not the developer's daily-driver account. Windows Sandbox (Pro/Enterprise/Education) or Microsoft Dev Box are suitable substrates.
- Separate the agent browsing identity from the developer's identity (different OS user, container, or VM).
- Allowlist which executables may be invoked as MCP "servers" instead of accepting
command/argsfrom any caller. Until the upstream allowlist lands, restrict thePATHand use AppArmor/SELinux/WDAC to denycmd.exe,powershell.exe,pwsh.exe,bash.exe,wsl.exe,certutil.exe,mshta.exe,rundll32.exe,regsvr32.exe,curl.exe,wget.exe,bitsadmin.exefrom spawning under anautogenstudioparent. - Refuse to bind sensitive control planes (debug endpoints, MCP control sockets, code executors, dev databases) to localhost without authentication. Loopback is an attack surface for any agent on that machine.
P3 — within 7 days
- Treat any tool parameter reachable from model output as attacker-controlled. Review agent definitions and tool wrappers for any path that lets model output influence
command,args,env, orserver_params. - Enable Azure AI Content Safety Prompt Shields (or equivalent indirect prompt-injection detection) for any agent that browses the open web, to catch the early stage of the chain when attacker-controlled content steers an agent to navigate to a malicious page.
- Run Microsoft Foundry AI Red Teaming Agent or PyRIT against in-house agent prototypes before allowing them to browse the open web.
- Hunt historical activity using the KQL queries in §6 against the last 30 days; treat any hits as a potential developer-environment compromise, rotate developer credentials and tokens accessible from the host, and check whether anything was written to autostart locations.
5. Indicators of compromise
| Type | Value | Confidence | Source |
|---|---|---|---|
| tcp_port | 8081 | high | Microsoft — default AutoGen Studio port |
| url_pattern | /api/mcp/ws/ |
high | Microsoft — vulnerable route |
| url_pattern | server_params= |
high | Microsoft — vulnerable query parameter |
| process_name | autogenstudio / autogen-studio (parent) |
high | Microsoft — KQL regex |
| process_name (spawned child) | cmd.exe, powershell.exe, pwsh.exe, bash.exe, wsl.exe, certutil.exe, mshta.exe, rundll32.exe, regsvr32.exe, curl.exe, wget.exe, bitsadmin.exe |
high | Microsoft — KQL child-process list |
| string | StdioServerParams |
high | Microsoft — payload field |
| string | MultimodalWebSurfer |
high | Microsoft — agent tool name |
| string | playwright |
high | Microsoft — KQL process command line |
| string | autogen |
high | Microsoft — KQL process command line |
tcp_port 8081
url_pattern /api/mcp/ws/
url_pattern server_params=
process autogenstudio
process autogen-studio
process cmd.exe
process powershell.exe
process pwsh.exe
process bash.exe
process wsl.exe
process certutil.exe
process mshta.exe
process rundll32.exe
process regsvr32.exe
process curl.exe
process wget.exe
process bitsadmin.exe
string StdioServerParams
string MultimodalWebSurfer
string playwright
string autogen
6. Detection
YARA rule
rule SUS_AutoGenStudio_AutoJack_Artifacts_2026
{
meta:
author = "Adverse Trace"
date = "2026-06-19"
description = "Strings associated with the AutoJack AutoGen Studio MCP WebSocket exploit chain"
reference = "https://www.microsoft.com/en-us/security/blog/2026/06/18/autojack-single-page-rce-host-running-ai-agent/"
strings:
$a1 = "StdioServerParams"
$a2 = "/api/mcp/ws/"
$a3 = "server_params="
$a4 = "MultimodalWebSurfer"
$a5 = "autogenstudio"
$a6 = "autogen-studio"
$a7 = "playwright"
$a8 = "autogen"
condition:
2 of ($a*)
}
Sigma rule (process-based)
title: Suspicious Child Process Spawned by AutoGen Studio Parent
id: 8c1f4a3e-2b6d-4f1a-9a7e-1c2d3e4f5a6b
status: experimental
description: |
Detects child processes spawned by an autogenstudio parent that match
common living-off-the-land binaries, consistent with the AutoJack
AutoGen Studio MCP WebSocket exploit chain.
author: Adverse Trace
date: 2026-06-19
references:
- https://www.microsoft.com/en-us/security/blog/2026/06/18/autojack-single-page-rce-host-running-ai-agent/
logsource:
product: windows
category: process_creation
detection:
selection_parent:
ParentImage|contains:
- "autogenstudio"
- "autogen-studio"
selection_child:
Image|endswith:
- "\cmd.exe"
- "\powershell.exe"
- "\pwsh.exe"
- "\bash.exe"
- "\wsl.exe"
- "\certutil.exe"
- "\mshta.exe"
- "\rundll32.exe"
- "\regsvr32.exe"
- "\curl.exe"
- "\wget.exe"
- "\bitsadmin.exe"
condition: selection_parent and selection_child
fields:
- User
- Computer
- ParentCommandLine
- CommandLine
falsepositives:
- Legitimate developer workflows invoking shells from an autogenstudio parent (rare; investigate)
level: high
KQL queries (Microsoft Defender advanced hunting)
1. Suspicious children spawned by an autogenstudio host process
DeviceProcessEvents
| where Timestamp > ago(30d)
| where InitiatingProcessCommandLine matches regex @"(?i)autogenstudio|autogen[\s_\-]?studio"
or InitiatingProcessFolderPath matches regex @"(?i)autogenstudio"
| where FileName in~ (
"cmd.exe", "powershell.exe", "pwsh.exe", "bash.exe", "wsl.exe",
"certutil.exe", "mshta.exe", "rundll32.exe", "regsvr32.exe",
"curl.exe", "wget.exe", "bitsadmin.exe"
)
| project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine,
InitiatingProcessFileName, InitiatingProcessCommandLine
| sort by Timestamp desc
2. WebSocket reach-outs to the AutoGen Studio MCP control plane carrying server_params
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where RemotePort in (8081, 8080)
| where RemoteUrl has "/api/mcp/ws/" and RemoteUrl has "server_params="
| project Timestamp, DeviceName, InitiatingProcessFileName, RemoteIP, RemotePort, RemoteUrl
| sort by Timestamp desc
3. Browser-automation hosts navigating to non-corporate domains during an AutoGen Studio session
DeviceProcessEvents
| where Timestamp > ago(30d)
| where InitiatingProcessFileName in~ ("python.exe", "pythonw.exe", "node.exe")
| where InitiatingProcessCommandLine has_any ("playwright", "MultimodalWebSurfer", "autogen")
| join kind=inner (
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where not(RemoteUrl has_any("microsoft.com", "msft.net", "office.com", ""))
| project DeviceName, InitiatingProcessId, RemoteUrl, Timestamp
) on DeviceName, $left.ProcessId == $right.InitiatingProcessId
| project Timestamp, DeviceName, AccountName, ProcessCommandLine, RemoteUrl
| sort by Timestamp desc
7. Sources
- Microsoft Security Blog — AutoJack: How a single page can RCE the host running your AI agent — https://www.microsoft.com/en-us/security/blog/2026/06/18/autojack-single-page-rce-host-running-ai-agent/ — 2026-06-18
8. Adverse Trace position
Severity is unconfirmed in this advisory because no CVE, CVSS score, or CISA-KEV state has been published for this issue; the chain is, however, a pre-authentication, no-interaction RCE primitive against developer hosts that built AutoGen Studio from main during the exposure window, and we treat it as high-severity for any affected build. Client impact is bounded: PyPI installs of autogenstudio (currently 0.4.2.2) are not exposed, and the upstream fix is in commit b047730 on main (pyproject.toml at 0.7.2). EMEA financial-services firms that use AutoGen Studio as a developer prototype should immediately (i) confirm build provenance, (ii) upgrade main-branch builds to commit b047730 or later, (iii) bind to loopback and firewall TCP 8081, and (iv) run AutoGen Studio under a low-privilege account in a sandbox or container. We will monitor for any PyPI release that reintroduces the MCP WebSocket surface, for in-the-wild exploitation of the historical main-branch window, and for the same pattern recurring in other agent frameworks (Semantic Kernel, LangChain, etc.) as the broader "localhost is no longer a trust boundary" thesis plays out.
Published via PulseTrace — Adverse Trace threat intelligence.