{"id":"GHSA-p4h8-56qp-hpgv","aliases":[],"status":"published","title":"SSH/SCP option injection allowing local RCE in @aiondadotcom/mcp-ssh","description":"## Impact\n\nA crafted `hostAlias` argument such as `-oProxyCommand=...` was passed to `ssh`/`scp` without an argument terminator. SSH interprets arguments starting with `-` as options regardless of position, so the option-injection caused SSH to execute the attacker-supplied `ProxyCommand` **locally** on the machine running the MCP server — before any network connection. This bypassed the documented protection of `# @password:` annotations and exposed local SSH keys, browser cookies, other MCP server credentials, and anything else readable by the server process.\n\nA second local-RCE vector existed on Windows: `spawn(..., { shell: true })` was used so that `ssh.exe`/`scp.exe` could be found via `PATH`. With `shell: true`, every argument is re-parsed by `cmd.exe`, so shell metacharacters (`\u0026`, `|`, `^`, `\u003e`, `\"`, `;`, …) in `hostAlias`, `command`, `localPath` or `remotePath` would have been interpreted by `cmd.exe` and could have triggered arbitrary local command execution on Windows.\n\nThe MCP server runs locally over STDIO, but the LLM driving it is not trusted: its tool arguments can be steered by **prompt injection** from any untrusted text the LLM ingests (web pages, e-mails, repository files, output of other MCP servers). The attack does not require a malicious user — only that the LLM ingests attacker-controlled text at any point during the session.\n\n## Patches\n\nFixed in **1.3.5**.\n\n- Add `--` argument terminator to all `ssh`/`scp` invocations.\n- Strict whitelist for `hostAlias` (rejects leading `-` and shell metacharacters).\n- Known-host check: every `hostAlias` must be defined in `~/.ssh/config` (including `Include` directives) or present in `~/.ssh/known_hosts`.\n- Resolve `ssh.exe`/`scp.exe` to absolute paths and use `shell: false` everywhere on Windows.\n\n## Workarounds\n\nNone. Upgrade to 1.3.5.\n\n## Credit\n\nReported by Pico (@piiiico) as part of an MCP server security audit.","severity":{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high","from":"ghsa"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-78","CWE-88"],"published":"2026-04-14T00:04:10Z","modified":"2026-04-14T00:28:04Z","fixes":[{"ecosystem":"npm","package":"@aiondadotcom/mcp-ssh","fixed_in":["1.3.5"],"sources":["ghsa","osv"]}],"affected":[{"source":"ghsa","ecosystem":"npm","package":"@aiondadotcom/mcp-ssh","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.3.5"}]}]},{"source":"osv","ecosystem":"npm","package":"@aiondadotcom/mcp-ssh","ranges":[{"type":"SEMVER","events":[{"introduced":"0"},{"fixed":"1.3.5"}]}]}],"references":[{"url":"https://github.com/AiondaDotCom/mcp-ssh/security/advisories/GHSA-p4h8-56qp-hpgv","tags":["web"]},{"url":"https://github.com/AiondaDotCom/mcp-ssh/issues/9","tags":["web"]},{"url":"https://github.com/AiondaDotCom/mcp-ssh/releases/tag/1.3.5","tags":["web"]},{"url":"https://github.com/advisories/GHSA-p4h8-56qp-hpgv"},{"url":"https://github.com/AiondaDotCom/mcp-ssh","tags":["package"]}],"sources":{"ghsa":[{"id":"GHSA-p4h8-56qp-hpgv","title":"SSH/SCP option injection allowing local RCE in @aiondadotcom/mcp-ssh","description":"## Impact\n\nA crafted `hostAlias` argument such as `-oProxyCommand=...` was passed to `ssh`/`scp` without an argument terminator. SSH interprets arguments starting with `-` as options regardless of position, so the option-injection caused SSH to execute the attacker-supplied `ProxyCommand` **locally** on the machine running the MCP server — before any network connection. This bypassed the documented protection of `# @password:` annotations and exposed local SSH keys, browser cookies, other MCP server credentials, and anything else readable by the server process.\n\nA second local-RCE vector existed on Windows: `spawn(..., { shell: true })` was used so that `ssh.exe`/`scp.exe` could be found via `PATH`. With `shell: true`, every argument is re-parsed by `cmd.exe`, so shell metacharacters (`\u0026`, `|`, `^`, `\u003e`, `\"`, `;`, …) in `hostAlias`, `command`, `localPath` or `remotePath` would have been interpreted by `cmd.exe` and could have triggered arbitrary local command execution on Windows.\n\nThe MCP server runs locally over STDIO, but the LLM driving it is not trusted: its tool arguments can be steered by **prompt injection** from any untrusted text the LLM ingests (web pages, e-mails, repository files, output of other MCP servers). The attack does not require a malicious user — only that the LLM ingests attacker-controlled text at any point during the session.\n\n## Patches\n\nFixed in **1.3.5**.\n\n- Add `--` argument terminator to all `ssh`/`scp` invocations.\n- Strict whitelist for `hostAlias` (rejects leading `-` and shell metacharacters).\n- Known-host check: every `hostAlias` must be defined in `~/.ssh/config` (including `Include` directives) or present in `~/.ssh/known_hosts`.\n- Resolve `ssh.exe`/`scp.exe` to absolute paths and use `shell: false` everywhere on Windows.\n\n## Workarounds\n\nNone. Upgrade to 1.3.5.\n\n## Credit\n\nReported by Pico (@piiiico) as part of an MCP server security audit.","status":"published","published":"2026-04-14T00:04:10Z","modified":"2026-04-14T00:04:10Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-78","CWE-88"],"updated_at":"2026-11-02T14:39:53.087746Z"}],"osv":[{"id":"GHSA-p4h8-56qp-hpgv","title":"SSH/SCP option injection allowing local RCE in @aiondadotcom/mcp-ssh","description":"## Impact\n\nA crafted `hostAlias` argument such as `-oProxyCommand=...` was passed to `ssh`/`scp` without an argument terminator. SSH interprets arguments starting with `-` as options regardless of position, so the option-injection caused SSH to execute the attacker-supplied `ProxyCommand` **locally** on the machine running the MCP server — before any network connection. This bypassed the documented protection of `# @password:` annotations and exposed local SSH keys, browser cookies, other MCP server credentials, and anything else readable by the server process.\n\nA second local-RCE vector existed on Windows: `spawn(..., { shell: true })` was used so that `ssh.exe`/`scp.exe` could be found via `PATH`. With `shell: true`, every argument is re-parsed by `cmd.exe`, so shell metacharacters (`\u0026`, `|`, `^`, `\u003e`, `\"`, `;`, …) in `hostAlias`, `command`, `localPath` or `remotePath` would have been interpreted by `cmd.exe` and could have triggered arbitrary local command execution on Windows.\n\nThe MCP server runs locally over STDIO, but the LLM driving it is not trusted: its tool arguments can be steered by **prompt injection** from any untrusted text the LLM ingests (web pages, e-mails, repository files, output of other MCP servers). The attack does not require a malicious user — only that the LLM ingests attacker-controlled text at any point during the session.\n\n## Patches\n\nFixed in **1.3.5**.\n\n- Add `--` argument terminator to all `ssh`/`scp` invocations.\n- Strict whitelist for `hostAlias` (rejects leading `-` and shell metacharacters).\n- Known-host check: every `hostAlias` must be defined in `~/.ssh/config` (including `Include` directives) or present in `~/.ssh/known_hosts`.\n- Resolve `ssh.exe`/`scp.exe` to absolute paths and use `shell: false` everywhere on Windows.\n\n## Workarounds\n\nNone. Upgrade to 1.3.5.\n\n## Credit\n\nReported by Pico (@piiiico) as part of an MCP server security audit.","status":"published","published":"2026-04-14T00:04:10Z","modified":"2026-04-14T00:28:04.463444Z","cvss":[{"version":"4.0","score":8.7,"vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N","level":"high"}],"cwes":["CWE-78","CWE-88"],"updated_at":"2026-11-02T15:46:52.534897Z"}]}}
