GHSA-g29h-pfmp-qp9r: High severity npm/codewhale vulnerability

Published Sep 4, 2026
·
Updated

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

4 affected componentsFixes available
npm/codewhale>=0.8.41<0.8.64
0.8.64
rust/codewhale-tui>=0.8.41<0.8.64
0.8.64
npm/deepseek-tui>=0.3.10<0.8.41
0.8.41
rust/deepseek-tui>=0.3.10<=0.8.41

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/codewhale to a version that resolves this vulnerability.

    Fixed in 0.8.64
  2. Upgrade

    Upgrade rust/codewhale-tui to a version that resolves this vulnerability.

    Fixed in 0.8.64
  3. Upgrade

    Upgrade npm/deepseek-tui to a version that resolves this vulnerability.

    Fixed in 0.8.41
  4. Upgrade

    Upgrade CodeWhale to a version that resolves this vulnerability.

    Fixed in 0.8.64
  5. Upgrade

    Upgrade to a fixed release to a version that resolves this vulnerability.

    Patch 57f3c89471e27ac4032d9791f6885e5d4408c381

Event History

Sep 4, 2026
Advisory Published
via GitHub·06:02 PM
Data Sourced
via GitHub·06:02 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

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.

2

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.

3

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.

4

What should be done to remediate this issue?

Upgrade to version 0.8.64 or later, which contains the fix in commit 57f3c89471e27ac4032d9791f6885e5d4408c381.

5

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.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203