The Repo Name Was a Shell Command: ai-sdlc MCP Server Command Injection

On 27 October 2026 CVE-2026-117558 was published for the ai-sdlc plugin MCP server: an OS command injection flaw (CWE-78) scored CVSS 7.8 affecting versions through 0.31.2. The check_issue and check_pr_status tools interpolated the unvalidated repo argument into gh issue view and gh pr view commands run via execSync(), so shell metacharacters in the value meant arbitrary command execution as the MCP server user. NVD’s own description names the delivery path explicitly: prompt-injected agents supplying a hostile repo value. The flaw was reported upstream as issue #1970 on 23 October and fixed the same day in PR #1982 (“spawn gh without a shell,” commit 717d7ecf).

The fix is the textbook correction and worth stating precisely: the tools now spawn gh with an argument array instead of a shell string, plus owner/name schema validation on the repo value, with new unit tests for both tools — which closes the CWE-78 path rather than blocklisting metacharacters. Note the scoring gap: the reporter’s issue claimed 9.8 (AV:N/PR:N), while NVD assigns 7.8 with AV:L and PR:L, treating exploitation as local and requiring low privileges — the calmer rating reflects that someone must get a malicious repo string into the tool call, whether a prompt-injected agent or a careless automation. The OSV record was still being updated on 29 October, and the affected-version list spans the plugin’s 0.9.0–0.31.2 lineage, so anyone running the MCP server at or below 0.31.2 should pull past the fix commit and confirm the release tag in the repository.

Why defenders should take this seriously — and where to discount it

The serious part is the pattern, not just the bug: MCP tool parameters are attacker-influenced input whenever an agent processes untrusted content, and a repo field that reaches a shell is a prompt-injection-to-RCE bridge — the same bridge class as the four MCP-tooling command-injection CVEs in VulnCheck’s October batch and Langflow’s MCP stdio sink. The discount: NVD’s local vector and privileges-required rating bounds this below the network-wormable class; exploitation runs as the MCP server user, so sandboxing and service-account hygiene contain the blast radius; and the upstream fix landed within hours of the report with tests attached. No exploitation is claimed anywhere we read. Treat it as harden-now input-validation debt for anyone hosting this MCP server, not an incident.

What it means for builders and defenders

  • Move the ai-sdlc MCP server past 0.31.2. Pull the fix (upstream commit 717d7ecf / PR #1982) and confirm your pinned plugin tag includes it.
  • Never pass tool parameters through a shell. Spawn subprocesses with argument arrays and validate structured inputs (owner/name schemas, allowlists) — the upstream fix is the reference pattern.
  • Assume every MCP tool argument is attacker-influenced. If an agent can be prompt-injected, its tool calls are injection vectors; threat-model tool inputs the way you threat-model HTTP query strings.
  • Run MCP servers as least-privilege users in sandboxes. The impact here was bounded by the server user’s rights — keep it that way with dedicated service accounts and no ambient credentials.

Our verification was read-only. The NVD record for CVE-2026-117558 was read first-hand in full (published 27 October 2026), including the description, CVSS 3.1 vector and score, and all references; the OSV record was read first-hand (published 27 October, modified 29 October), including the summary, severity, affected range, and fix commit; upstream issue #1970 was read first-hand via the GitHub API (title, dates, state, reporter severity claim, affected files); and the fix commit 717d7ecf / PR #1982 was read first-hand via the GitHub API (message, date, and changed files including the new tests). The VulnCheck advisory was used as a corroborating reference. No code was run, no MCP server was deployed, no payload was tested, and no maintainer was contacted. Brave Search was used for discovery only.

Sources: