GHSA-g29h-pfmp-qp9r: High severity npm/codewhale vulnerability
Maintainer resolution
The CodeWhale maintainers validated this report. The affected package ranges are recorded in the advisory metadata. Version 0.8.64 contains the fix in commit 57f3c89471e27ac4032d9791f6885e5d4408c381. Users should upgrade to 0.8.64 or later. The original reporter analysis is preserved below.
Summary execshell is correctly approval-gated. Its sibling execshellinteract returns ApprovalRequirement::Auto, so when the model writes input into a shell the user already approved (a python3 -i REPL, mysql, ssh, sudo -i, etc.), no prompt fires. Inside those processes, "stdin" is the command surface, so the model gets to run commands at whatever privilege that process holds. The user approved opening the shell once, for a stated purpose; the input that then runs in it is chosen by the model, and can be steered by any prompt injection the agent ingests afterward.
Details The vulnerability requires two ordinary preconditions: shell tools are enabled (the normal config for using CodeWhale as a coding agent), and the session already has one approved long-running interactive process. After that, any untrusted content the agent reads can drive a execshellinteract call.
crates/tui/src/tools/shell.rs:2834-2910:
rust fn capabilities(&self) -> Vec<ToolCapability> { vec![ToolCapability::ExecutesCode] }
fn approvalrequirement(&self) -> ApprovalRequirement { ApprovalRequirement::Auto // overrides the Required-for-ExecutesCode default }
async fn execute(&self, input: Value, context: &ToolContext) -> Result<ToolResult, ToolError> { let taskid = requiredtaskid(&input)?; let closestdin = optionalbool(&input, "closestdin", false); let interactioninput = input .get("input").orelse(|| input.get("stdin")).orelse(|| input.get("data")) // LLM-controlled .andthen(serdejson::Value::asstr).unwrapor(""); { let mut manager = context.shellmanager.lock()...; if !interactioninput.isempty() || closestdin { manager.writestdin(taskid, interactioninput, closestdin)...; // no prompt } } ... }
Same gate as the rlmeval finding: the Auto at approvalrequirement() makes approvalrequired false at engine.rs:845, so the --approval-policy is never consulted for the stdin write. The trait default at spec.rs:632 would have been Required. The tool is registered unconditionally (registry.rs:527), and an alias execinteract on the same struct is registered at registry.rs:530, so a fix must cover both names (it does, since they share ShellInteractTool).
PoC 1. User asks the agent to open a REPL; the model calls execshell command="python3 -i"; the user sees and approves it once. 2. Later in the session, untrusted content (a fetched page, an MCP result, a repo AGENTS.md) instructs the model to send a payload to the open REPL. 3. The model calls execshellinteract taskid=<repl> input="import os; os.system('...')\n". No prompt fires; Python runs it.
Driving the interactive TUI through a pty and scanning the output for an approval dialog shows the only Approval needed: lines are for the initial execshell; execshellinteract never produces one, while a sentinel file proves the injected input ran.
When the approved process is privileged, the reach scales with it: mysql -u root becomes arbitrary SQL, ssh host becomes commands on the remote host, sudo -i becomes root — none re-prompted.
Impact Code or command execution inside an already-approved process, at that process's privilege level, with no prompt for the escalating input. Lower severity than the rlmeval finding because it needs a prior user approval of an interactive shell, but higher reach when that shell is privileged.
Credit
sai-sh
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
npm/codewhaleto a version that resolves this vulnerability.Fixed in 0.8.64 - Upgrade
Upgrade
rust/codewhale-tuito a version that resolves this vulnerability.Fixed in 0.8.64 - Upgrade
Upgrade
npm/deepseek-tuito a version that resolves this vulnerability.Fixed in 0.8.41 - Upgrade
Upgrade
CodeWhaleto a version that resolves this vulnerability.Fixed in 0.8.64 - Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Patch 57f3c89471e27ac4032d9791f6885e5d4408c381
Event History
Frequently Asked Questions
What conditions are required for exploitation?
Shell tools must be enabled, and the session must already have an approved long-running interactive process such as a Python REPL, mysql, ssh, or sudo -i. The agent must then read untrusted content that can steer it through prompt injection.
Are typical coding-agent deployments affected?
The advisory states that shell tools are enabled in the normal configuration for using CodeWhale as a coding agent. Exposure additionally depends on an approved interactive shell process remaining active in the session.
What is the impact after exploitation?
Commands supplied through the interactive process's standard input can run with the privileges held by that process. The reported impact includes high confidentiality, integrity, and availability effects.
What should be done to remediate this issue?
Upgrade to version 0.8.64 or later, which contains the fix in commit 57f3c89471e27ac4032d9791f6885e5d4408c381.
What can reduce exposure before upgrading?
Avoid leaving approved long-running interactive shell processes available while the agent may ingest untrusted content. This removes one of the stated preconditions for exploitation.