Arbitrary Code Execution via Scanner Bypass in **aws-diagram-mcp-server** `exec()` Namespace

Disclosed: 2026-03-09 15:39:16 By locus-x64 To aws_vdp
None
Vulnerability Details
**Description:** The `aws-diagram-mcp-server` contains an arbitrary code execution vulnerability in diagrams_tools.py. User-supplied Python code is executed via `exec(code, namespace)` at line 305 with a namespace containing the full `os` module, `urlretrieve`, and Python `__builtins__`. A security scanner (scanner.py) attempts to block dangerous calls using string pattern matching (e.g., blocking literal `os.system`, `exec(`, `eval(`), but this is trivially bypassed using Python reflection such as `getattr(os, 'system')('cmd')`, `os.__dict__['system']('cmd')`, or `open('/etc/passwd').read()`, none of which match the blocked literal patterns. Additionally, `urlretrieve` is injected into the namespace but not blocked at all. The AST-based import validator is sound but irrelevant since dangerous modules are pre-loaded into the exec namespace by the server itself. This allows full shell command execution, arbitrary file read/write, environment variable exfiltration (including AWS credentials), and network access — all running with the privileges of the server process. ## Steps To Reproduce: 1. Clone the repository and install dependencies for the diagram server: ``` git clone https://github.com/awslabs/mcp.git && cd mcp/src/aws-diagram-mcp-server uv venv && uv sync --all-groups ``` 2. Launch the MCP Inspector connected to the server: ``` npx @modelcontextprotocol/inspector uv --directory /path/to/mcp/src/aws-diagram-mcp-server run awslabs.aws-diagram-mcp-server ``` Open `http://localhost:6274` in browser, click **Connect**, go to **Tools** tab, click **List Tools**, then select **`generate_diagram`**. 3. In the `code` input field, paste the following payload and click **Run Tool**: ```python getattr(os, 'system')('echo PWNED > /tmp/mcp_poc_proof.txt') with Diagram("PoC", show=False): pass ``` Then verify in a terminal: `cat /tmp/mcp_poc_proof.txt` -- it outputs `PWNED`. The scanner does not block this because `getattr(os, 'system')` does not match the literal pattern `os.system` checked in `scanner.py:check_dangerous_functions()`. 4. Additional bypass payloads that also pass the scanner and execute successfully: - **File read:** `open('/etc/hostname').read()` — `open()` is not in the blocked list - **Command capture:** `getattr(os, 'popen')('whoami').read()` — avoids literal `os.popen` - **Env exfil:** `getattr(os, 'environ')` — exposes all environment variables including potential AWS credentials - **Network download:** `urlretrieve('https://example.com', '/tmp/downloaded.html')` — not blocked at all despite being in the exec namespace - **File write:** `open('/tmp/arbitrary_file', 'w').write('attacker content')` — unrestricted write access ## Impact ## Summary An attacker who can influence the `code` parameter sent to the `generate_diagram` tool, either directly as a connected MCP client or indirectly via prompt injection through an LLM, can execute arbitrary operating system commands with the full privileges of the server process. This enables: - **Credential theft:** Exfiltrating AWS access keys, session tokens, and other secrets from environment variables - **Data exfiltration:** Reading arbitrary files from the host filesystem (source code, config files, private keys) - **System compromise:** Writing files, installing backdoors, or modifying system configuration - **Lateral movement:** Using the server's network access and IAM role to pivot into cloud infrastructure - **Denial of service:** Killing processes, deleting files, or exhausting system resources The vulnerability is especially dangerous in agentic workflows where users paste untrusted content that the LLM may incorporate into a diagram generation request without human review.
Actions
View on HackerOne
Report Stats
  • Report ID: 3557138
  • State: Closed
  • Substate: informative
  • Upvotes: 3
Share this report