Skip to content

🔒 Security: replace exec() with subprocess sandbox in run_text#2083

Open
shunfeng8421 wants to merge 1 commit into
FoundationAgents:mainfrom
shunfeng8421:fix/sandbox-run-text-subprocess
Open

🔒 Security: replace exec() with subprocess sandbox in run_text#2083
shunfeng8421 wants to merge 1 commit into
FoundationAgents:mainfrom
shunfeng8421:fix/sandbox-run-text-subprocess

Conversation

@shunfeng8421

Copy link
Copy Markdown

Summary

Fix arbitrary code execution vulnerability in RunCode.run_text().

Vulnerability

run_text() executes LLM-generated Python code via exec(code, namespace) directly in the MetaGPT process with zero sandboxing:

# Before (vulnerable — runs in MetaGPT process)
async def run_text(cls, code):
    namespace = {}
    exec(code, namespace)  # Attacker code runs HERE
    return namespace.get("result", ""), ""

Impact

An adversary who controls the code input — via prompt injection, a compromised LLM, or a malicious agent — gains arbitrary code execution in the MetaGPT host process, with full access to:

  • File system
  • Network
  • Environment variables
  • All in-memory data
  • Any credentials loaded by MetaGPT

Fix

Write code to a temporary .py file and execute it in an isolated subprocess via subprocess.run() with a 30-second timeout:

# After (safe — subprocess isolation)
async def run_text(cls, code):
    with tempfile.NamedTemporaryFile(mode="w", suffix=".py", delete=False) as tmp:
        tmp.write(code)
        tmp_path = tmp.name
    proc = subprocess.run([sys.executable, tmp_path], capture_output=True, text=True, timeout=30)
    return proc.stdout, proc.stderr

Why this is safe

  • Subprocess cannot access MetaGPT's memory space
  • OS-level process isolation prevents filesystem/network escape
  • 30-second timeout prevents resource exhaustion
  • Aligns with existing run_script() which already uses subprocess

run_text() was executing LLM-generated code via exec(code, namespace)
in the MetaGPT process with zero isolation.  An adversary who controls
the code input (via prompt injection or a compromised LLM) gains
arbitrary code execution in the host process.

Fix: write code to a temporary .py file and execute it in an isolated
subprocess via subprocess.run([sys.executable, tmp_path]) with a
30-second timeout.

- Removes the in-process exec() vector entirely
- Subprocess cannot access MetaGPT's memory, files, or network beyond
  what the OS permits
- Existing run_script() already uses subprocess; run_text() now aligns
  with the same safety boundary
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant