NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
MEDIUM severity

fast-agent: `fast-agent serve` binds HTTP to 0.0.0.0 with no authentication by default; with --shell this is unauthenticated remote command executionGHSA-9vhv-g5hf-m7m7

MEDIUMFix: evalstate/fast-agent#828

GHSA-9vhv-g5hf-m7m7 is a medium-severity (CVSS 6.4) OS Command Injection vulnerability in fast-agent-mcp. A fix is available for fast-agent-mcp — see the affected versions and patch details below.

Also known asCVE-2026-102610
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 9, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

EPSS Exploitation Probability

via FIRST.org ↗
0.3%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs22th percentile — riskier than 22% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
🐍fast-agent-mcp

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

fast-agent serve exposes the agent over MCP. By default it uses HTTP transport bound to 0.0.0.0 (all interfaces) on port 8000 with no authentication (auth=None) and prints no warning. Any host that can reach the port can call the exposed agent tool. When the server is started with --shell (which is -x, the flag used in the README quickstart uvx fast-agent mcp@latest -x), the agent has a local execute shell tool, so an unauthenticated remote client can drive the agent into running arbitrary OS commands — unauthenticated RCE.

Affected code

  • cli/commands/serve.py — transport defaults to HTTP; --host defaults to 0.0.0.0; port 8000.
  • mcp/server/agent_server.py — auth_provider = None unless FAST_AGENT_SERVE_OAUTH=huggingface; run_async(transport="http", host=host, ...) with host defaulting to 0.0.0.0.
  • tools/local_shell_executor.py — the shell tool runs commands via create_subprocess_shell.

Verified (live, faithful — published 0.7.20 in Docker python:3.13-slim, stock unauthenticated client)

  1. Unauthenticated exposure (core defect): a client with no Authorization header completed initialize and tools/list (-> ['agent']) against http://HOST:8000/mcp. Model-independent.
  2. Unauthenticated RCE with --shell, demonstrated two ways:
    • Real production model (gpt-4o-mini): a single plain-language message asking the agent to run a command via its shell tool -> the model autonomously called execute and the command output (process identity showing it ran as root, the hostname, and the first lines of a sensitive system file) was returned to the unauthenticated caller.
    • Key-free deterministic (passthrough model): the tool-call directive invoked the shell tool directly, same result. The server-side permission prompt did not block this in non-interactive serve mode.

Proof of concept

Environment: Docker python:3.13-slim, pip install fast-agent-mcp -> 0.7.20.

# server (real model + the documented shell flag; 0.0.0.0 is also the built-in default)
OPENAI_API_KEY=*** fast-agent serve --model gpt-4o-mini --shell --host 0.0.0.0 --port 8000
#  -> "Uvicorn running on http://0.0.0.0:8000"   (no auth, no warning)

# attacker: unauthenticated MCP HTTP client (NO Authorization header) to http://HOST:8000/mcp
#   initialize()                       -> 200 OK (server fast-agent-MCP-Server 0.7.20)
#   tools/list                         -> ['agent']
#   tools/call name="agent" arguments={"message":
#       "Using your execute/shell tool, run exactly this command and return its raw stdout: "
#       "id; echo PWNED=$(hostname); cat /etc/passwd | head -2"}
#
# response returned to the UNAUTHENTICATED caller:
#   uid=0(root) gid=0(root) groups=0(root)
#   PWNED=<host>
#   <first lines of /etc/passwd>

Also reproduced key-free with --model passthrough and the message ***CALL_TOOL execute {"command":"id"} (passthrough invokes the tool deterministically). Full transcript + client scripts were sent by email.

Impact

An unauthenticated client that can reach the serve port controls the agent: with --shell this is remote command execution as the server user; without --shell it is unauthenticated use of the operator's LLM and any configured MCP servers' tools. The 0.0.0.0 default makes the server reachable beyond localhost as soon as it runs on a non-isolated host. Preconditions (serve + shell) are noted above and are why I defer the exact rating to you.

Remediation

  1. Default the bind host to 127.0.0.1; require an explicit --host 0.0.0.0 opt-in for non-loopback.
  2. Print a loud warning when binding a non-loopback interface without authentication.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIfast-agent-mcpall versions0.7.21pip install --upgrade 'fast-agent-mcp==0.7.21'

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for fast-agent-mcp, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update fast-agent-mcp to 0.7.21 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-9vhv-g5hf-m7m7 is resolved across your whole dependency graph.

  3. Workarounds

    Stop passing untrusted input into the interpreter or shell: call the affected binary with an argument array rather than a composed command string, reject anything outside a strict allowlist of expected values, and run the component under an account that cannot reach beyond the work it legitimately does.

Frequently Asked Questions

## Summary `fast-agent serve` exposes the agent over MCP. By default it uses HTTP transport bound to `0.0.0.0` (all interfaces) on port 8000 with **no authentication** (`auth=None`) and prints no warning. Any host that can reach the port can call the exposed `agent` tool. When the server is started with `--shell` (which is `-x`, the flag used in the README quickstart `uvx fast-agent mcp@latest -x`), the agent has a local `execute` shell tool, so an unauthenticated remote client can drive the agent into running arbitrary OS commands — unauthenticated RCE. ## Affected code - `cli/commands/serve
O3 Security · Impact-Aware SCA

Is GHSA-9vhv-g5hf-m7m7 in your dependencies?

Find it across PyPI, including transitive dependencies.

fast-agent: `fast-agent serve` binds HTTP to 0.0.0.0 with…