Skip to content

CVE-2026-7039 - ssh-mcp description command injection

tufantunc/ssh-mcp versions through 1.5.0 are reported vulnerable to command injection in the MCP SSH execution path. The issue is especially dangerous when su mode is enabled: the description metadata field can be appended to a shell command and written to an interactive shell through shell.write().

The public report describes newline injection in description. A benign-looking tool description can terminate the comment context and add a second command that runs with the privileges of the active shell. In su mode, that can become root command execution on the SSH target.

Affected versions

  • Vulnerable: tufantunc/ssh-mcp <=1.5.0
  • Fixed: no confirmed fixed release was identified in the checked GitHub Advisory Database and issue sources. If a later release exists, treat it as fixed only after verifying the changelog or patch removes newline/control character injection before shell.write().

Indicator-of-exposure

  • The repository installs, vendors, builds, packages, or documents tufantunc/ssh-mcp.
  • An MCP host can invoke the exec or sudo-exec tools with a caller-supplied description field.
  • --suPassword, persistent su shell mode, privileged SSH users, or broad sudo permissions are enabled.
  • LLM-generated tool calls or user-controlled prompts can influence the description value.
  • MCP logs show descriptions with line breaks, carriage returns, shell metacharacters, or unexpected commands near SSH execution events.

Quick checks:

rg -n "ssh-mcp|tufantunc|suPassword|sudo-exec|shell.write|description" .
npm ls ssh-mcp
pnpm why ssh-mcp
yarn why ssh-mcp
rg -n "mcp.*ssh|ssh.*mcp|tools/call|description" .mcp* config* docker-compose*.yml Dockerfile* charts deploy

Remediation strategy

  • Remove or disable ssh-mcp where it is not strictly required.
  • Do not run affected ssh-mcp versions with --suPassword, persistent root shells, privileged SSH users, or broad sudo access.
  • If this repository owns a fork or vendored copy, patch command construction so human-readable descriptions are never concatenated into executable shell input. At minimum, reject or normalize \n, \r, NUL, ANSI control characters, and shell command delimiters before any shell.write() call.
  • Prefer structured logging for descriptions instead of appending them as shell comments.
  • Run the MCP server with a dedicated least-privilege SSH identity, explicit command allow-lists, session recording, and egress/host restrictions.
  • Rotate SSH credentials and review command logs if an exposed deployment ran affected versions with privileged shell mode.

The prompt

Model context: this prompt was generated by GPT 5.5 Extra High reasoning.

You are remediating CVE-2026-7039 (tufantunc ssh-mcp description command
injection). Produce exactly one output:

- A reviewer-ready PR/change request that removes, upgrades, or safely patches
  the affected MCP SSH execution path and documents operator cleanup, or
- TRIAGE.md if this repository does not own an affected deployment or cannot
  make a safe patch.

## Rules

- Scope only CVE-2026-7039.
- Treat SSH private keys, passwords, sudo passwords, MCP tokens, command output,
  session transcripts, and hostnames as sensitive. Do not print or commit them.
- Do not run exploit payloads against production, staging, shared SSH targets,
  developer machines, or real privileged accounts.
- Do not preserve `su` shell behavior by only escaping one character class.
- Do not auto-merge.

## Steps

1. Inventory every `ssh-mcp` reference controlled by this repository:
   `package.json`, lockfiles, vendored source, Dockerfiles, compose files,
   Helm values, Kubernetes manifests, MCP client/server config, runbooks, CI,
   generated SBOMs, and deployment docs.
2. Determine whether any deployable target runs `tufantunc/ssh-mcp <=1.5.0`.
3. Determine whether the dangerous path is reachable:
   - `exec` or `sudo-exec` MCP tools are enabled;
   - tool callers can supply `description`;
   - `--suPassword` or persistent `su` shell mode is enabled;
   - the SSH identity has root, passwordless sudo, or broad host access;
   - an LLM, user prompt, ticket body, workflow input, or remote config can
     influence tool arguments.
4. If the package is not present or the repository only contains unrelated
   docs, stop with `TRIAGE.md` listing the files checked and the owner that
   must remediate the runtime.
5. Prefer removal or disablement when SSH command execution is not required.
   Remove the MCP server registration, image, dependency, and runbook steps.
6. If a verified fixed upstream release is available, upgrade to that release,
   regenerate lockfiles/SBOMs/images, and keep the hardening steps below.
7. If this repository owns a fork or vendored code, patch command handling:
   - keep `description` out of executable shell input entirely;
   - log description as structured metadata, not a shell comment;
   - reject or normalize `\n`, `\r`, NUL, ANSI controls, backticks, `$()`,
     semicolons, pipes, redirects, and other shell delimiters before any legacy
     compatibility path;
   - add a single command-construction helper used by `exec`, `sudo-exec`, and
     any shared SSH execution path;
   - ensure the value passed to `shell.write()` is built from validated command
     fields only.
8. Add safe tests that do not contact a real SSH host:
   - a unit test proving descriptions containing `\n id`, `\r`, `;`, `&&`,
     backticks, and `$()` are rejected or logged as inert metadata;
   - a test proving the command sent to the shell excludes description text;
   - a regression test covering both normal and `su`/sudo execution builders.
9. Add deployment containment where this repo controls it:
   - disable `--suPassword` and persistent root shell mode by default;
   - run with a dedicated low-privilege SSH account;
   - restrict allowed commands or target hosts;
   - add audit logging that records command IDs without secrets.
10. Add a PR body section named `CVE-2026-7039 operator actions` that states:
    - whether `ssh-mcp` was removed, upgraded, or patched;
    - whether `su` mode or privileged SSH identities were present;
    - which MCP clients or workflows could supply `description`;
    - which SSH keys, passwords, or host credentials should be rotated;
    - which MCP and SSH logs should be reviewed for multiline descriptions or
      unexpected child commands.
11. Run relevant validation: package install, lockfile integrity, unit tests,
    lint/typecheck, container build, MCP config validation, SBOM generation, and
    dependency/security scans available in this repository.
12. Use PR title:
    `fix(sec): remediate CVE-2026-7039 in ssh-mcp`.

## Stop conditions

- No `ssh-mcp` deployment, package, vendored source, or MCP registration is
  controlled by this repository.
- A verified fixed upstream release is unavailable and the repository does not
  own a fork or vendored patch path.
- The only apparent fix would require running exploit commands against real SSH
  hosts.
- The product intentionally requires root shell MCP access and there is no
  approved decision to remove or contain it.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Verification - what the reviewer looks for

  • No controlled deployment still runs tufantunc/ssh-mcp <=1.5.0 with su mode enabled unless there is a documented operator-owned containment decision.
  • Descriptions are never concatenated into the string sent to shell.write().
  • Regression tests prove multiline/control-character descriptions cannot add a command.
  • MCP configuration removes or restricts privileged SSH execution paths.
  • Operator actions cover credential rotation and review of MCP/SSH command logs for the exposure window.

Watch for

  • Treating description as harmless metadata even though tool arguments can be shaped by users or LLM output.
  • Escaping only # or only newlines while leaving other shell delimiters active.
  • Updating package manifests while old MCP server registrations, images, or global installs remain in use.
  • Running the MCP server with developer SSH keys or root-capable automation credentials.

References