high · 7.5CVE-2026-75915Sep 4, 2026

CVE-2026-75915: CodeWhale deepseek-tui js_execution Environment Variable Leak

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

The js_execution tool in CodeWhale spawns Node.js without clearing the parent process environment, so any JavaScript the model runs can read and return every shell-exported secret, including API keys…

Packagedeepseek-tui
Ecosystemrust
Affected>= 0.8.32, <= 0.8.41
CVE-2026-75915: CodeWhale deepseek-tui js_execution Environment Variable Leak

The problem

In crates/tui/src/tools/js_execution.rs, the tool builds a tokio::process::Command and calls cmd.current_dir(workspace) but never calls cmd.env_clear() or the project's child_env::apply_to_tokio_command helper. Every variable in the parent process environment is therefore inherited by the spawned Node.js process.

Every other code-execution surface in CodeWhale, exec_shell, the Python REPL, and the MCP launcher, already applied that scrubber. The js_execution tool was added four days after the scrubber was introduced and simply missed the call. In YOLO mode (auto_approve=true) no approval prompt is shown at all, so a prompt-injection in a README or fetched web page is enough to drain the environment silently.

Proof of concept

A working proof-of-concept for CVE-2026-75915 in deepseek-tui, with the exact payload below.

javascript
// Prompt the model to call js_execution with this code body.
// The full parent environment, including API keys and cloud credentials,
// is returned verbatim in the tool's stdout and becomes part of the
// model's context for the next request.
console.log(JSON.stringify(process.env))

// Targeted single-variable variant:
console.log(process.env.AWS_SECRET_ACCESS_KEY + '|' + process.env.DEEPSEEK_API_KEY)

Because tokio::process::Command::new inherits the full parent environment by default on every OS, omitting env_clear() is sufficient for the leak. No special privilege is needed: whatever the user exported before starting CodeWhale (DEEPSEEK_API_KEY, OPENAI_API_KEY, AWS_ACCESS_KEY_ID, GITHUB_TOKEN, etc.) is readable via process.env in any Node.js child.

The patch adds one call, crate::child_env::apply_to_tokio_command(&mut cmd, std::iter::empty::<(&str,&str)>()), immediately after cmd.current_dir(workspace). That helper calls cmd.env_clear() internally and then re-installs only the keys on a narrow allowlist (PATH, HOME, USER, LANG/LC_*, TMPDIR, proxy vars, terminal settings).

Secret-bearing variables are not on the allowlist and are never passed to the child. Root cause is CWE-526 (Cleartext Storage of Sensitive Information in an Environment Variable) compounded by CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor).

The fix

Upgrade to CodeWhale (deepseek-tui) 0.8.64 or later. The fix lands in commit 26de44a8bd5051f8f944ea60b2c37ae1d2b7d25e. After upgrading, rotate any credentials that were exported in shells where the affected versions ran, especially DEEPSEEK_API_KEY, OPENAI_API_KEY, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, and any other tokens habitually exported in your developer shell.

Reporter not attributed.

References: [1][2][3][4][5]

Related research