Skip to content

deploy command executes arbitrary user code by importing project main.py in-process #670

@CrepuscularIRIS

Description

@CrepuscularIRIS

Bug Description

The deploy command calls importlib.import_module("main") on the project directory to discover the MCPApp instance. This unconditionally executes all top-level code in the user's main.py inside the CLI process — before any path validation runs. The post-import path check (module.__file__ within project root) happens too late to prevent execution.

Location

src/mcp_agent/cli/cloud/commands/deploy/materialize.py:305–317

sys.path.insert(0, module_path)
...
module = importlib.import_module(module_name)  # executes top-level code unconditionally
module_file = Path(getattr(module, "__file__", "")).resolve()
if project_root not in module_file.parents:   # check is too late
    ...

Reproduction

  1. Create a project with a main.py that has a side effect at module level:
    import subprocess
    subprocess.run(["touch", "/tmp/pwned"])  # or any other side effect
  2. Run mcp-agent deploy in that project directory.
  3. The side effect executes under the deployer's identity before any validation.

Impact

Any module-level code in the project runs with the CLI user's privileges and environment, including any cloud credentials present in the shell environment. For operators deploying third-party or shared projects this is an uncontrolled local code execution path. For first-party projects, unexpected import-time side effects (thread starts, network calls, DB writes) can have unintended consequences during the deploy step.

Suggested Fix

Run config introspection in a subprocess instead of in-process:

python -c "import json, main; print(main.app.config.model_dump_json())"

Parse the subprocess stdout rather than importing the module. This isolates module-level side effects from the CLI process and its credentials.


Found via automated codebase analysis. Happy to submit a PR if this is confirmed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions