CVE-2026-75915
CodeWhale before 0.8.64 Environment Variable Leak via js_execution
CodeWhale versions before 0.8.64 contain an environment variable exposure vulnerability in the js_execution tool that fails to scrub parent process environment variables before spawning Node.js. Attackers can craft malicious JavaScript code executed by the tool to read process.env and leak API keys, cloud credentials, and authentication tokens back to the model context.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
8.7
CodeWhale before 0.8.64 Environment Variable Leak via js_execution
CodeWhale versions before 0.8.64 contain an environment variable exposure vulnerability in the js_execution tool that fails to scrub parent process environment variables before spawning Node.js. Attackers can craft malicious JavaScript code executed by the tool to read process.env and leak API keys, cloud credentials, and authentication tokens back to the model context.
- Record
CVE-2026-75915- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-200
- Updated
- 2026-11-02
EUVDEUVD-2026-60973
8.7
CodeWhale versions before 0.8.64 contain an environment variable exposure vulnerability in the js_execution tool that fails to scrub parent process environment variables before spawning Node.js. Attackers can craft malicious JavaScript code executed by the tool to read process.env and leak API keys, cloud credentials, and authentication tokens back to the model context.
- Record
EUVD-2026-60973- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-h539-c7r8-3xq4
8.7
CodeWhale: js_execution leaks parent environment to model context via missing env scrub
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 26de44a8bd5051f8f944ea60b2c37ae1d2b7d25e. Users should upgrade to 0.8.64 or later. The original reporter analysis is preserved below.
Summary
js_execution exposes parent process environment to model-provided JavaScript
The js_execution tool spawns Node with tokio::process::Command::new without calling the child_env scrubber that exec_shell, the Python REPL, and the MCP launcher all use. Model-provided JavaScript reads process.env and the values flow back to the parent transcript as the tool's stdout, exposing API keys, cloud credentials, and forge tokens to the next model turn.
Details
In crates/tui/src/tools/js_execution.rs (v0.8.37, lines 91-105):
let temp_dir = tempfile::tempdir()
.map_err(|e| ToolError::execution_failed(format!("tempdir failed: {e}")))?;
let script_path = temp_dir.path().join("js_execution.js");
tokio::fs::write(&script_path, code)
.await
.map_err(|e| ToolError::execution_failed(format!("tempfile write failed: {e}")))?;
let mut cmd = tokio::process::Command::new(&node);
cmd.arg(&script_path);
cmd.current_dir(workspace);
let output = tokio::time::timeout(Duration::from_secs(120), cmd.output())
.await
.map_err(|_| ToolError::Timeout { seconds: 120 })
.and_then(|res| res.map_err(|e| ToolError::execution_failed(e.to_string())))?;
The Command is built without cmd.env_clear() and without the project's crate::child_env::apply_to_tokio_command helper. Every variable in the parent process environment is inherited by the spawned node.
For comparison, exec_shell (crates/tui/src/tools/shell.rs:790-792) and the Python REPL (crates/tui/src/repl/runtime.rs:238) both apply the scrubber:
child_env::apply_to_command(&mut cmd, child_env::string_map_env(&exec_env.env));
apply_to_tokio_command calls cmd.env_clear() and then re-installs only the keys that pass is_allowed_parent_env_key (PATH, HOME, USER, LANG/LC_*, TMPDIR, proxy variables, Windows toolchain context, terminal settings). Secret-bearing variables (DEEPSEEK_API_KEY, OPENAI_API_KEY, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, etc.) are not on the allowlist and are dropped before the child starts. The js_execution path bypasses both the env_clear and the allowlist.
Commit history makes the gap explicit. Commit e6d4eae fix(security): scrub child process environments (2026-05-08) introduced child_env.rs and rewrote exec_shell, the Python REPL, the MCP launcher, and main.rs to use it. Commit 2566f3c feat(tools): add js_execution tool (2026-05-12) added this file four days later and never picked up the helper.
The tool is described to the model and surfaced in the approval pane as "Run model-provided JavaScript code in local Node.js execution sandbox" (crates/tui/src/core/engine/turn_loop.rs:1174-1176). No sandbox is applied beyond a 120-second timeout; Node has full filesystem and network access in addition to the inherited environment. The wording understates the trust boundary that the user is being asked to cross.
In YOLO mode (auto_approve=true) the JS body runs without any prompt at all, so a single adversarial prompt-injection from a README, fetched web page, or MCP server output drains the parent environment to the next model turn.
PoC
A standalone Cargo test reproduces the unscrubbed-env behavior. Save as crates/tui/tests/js_execution_env_leak.rs and run with cargo test -p deepseek-tui --test js_execution_env_leak -- --nocapture:
use deepseek_tui::tools::js_execution::execute_js_execution_tool;
use serde_json::json;
use tempfile::tempdir;
#[tokio::test]
async fn js_execution_inherits_parent_secrets() {
if deepseek_tui::dependencies::resolve_node().is_none() {
eprintln!("node not on PATH; skipping");
return;
}
unsafe {
…
- Record
GHSA-h539-c7r8-3xq4- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-200, CWE-526
- Updated
- 2026-11-02
NVD
8.7
CodeWhale versions before 0.8.64 contain an environment variable exposure vulnerability in the js_execution tool that fails to scrub parent process environment variables before spawning Node.js. Attackers can craft malicious JavaScript code executed by the tool to read process.env and leak API keys, cloud credentials, and authentication tokens back to the model context.
- Record
CVE-2026-75915- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-200
- Updated
- 2026-11-02
OSV
8.7
CodeWhale before 0.8.64 Environment Variable Leak via js_execution
CodeWhale versions before 0.8.64 contain an environment variable exposure vulnerability in the js_execution tool that fails to scrub parent process environment variables before spawning Node.js. Attackers can craft malicious JavaScript code executed by the tool to read process.env and leak API keys, cloud credentials, and authentication tokens back to the model context.
- Record
CVE-2026-75915- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-200
- Updated
- 2026-11-02
OSVGHSA-h539-c7r8-3xq4
8.7
CodeWhale: js_execution leaks parent environment to model context via missing env scrub
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 26de44a8bd5051f8f944ea60b2c37ae1d2b7d25e. Users should upgrade to 0.8.64 or later. The original reporter analysis is preserved below.
Summary
js_execution exposes parent process environment to model-provided JavaScript
The js_execution tool spawns Node with tokio::process::Command::new without calling the child_env scrubber that exec_shell, the Python REPL, and the MCP launcher all use. Model-provided JavaScript reads process.env and the values flow back to the parent transcript as the tool's stdout, exposing API keys, cloud credentials, and forge tokens to the next model turn.
Details
In crates/tui/src/tools/js_execution.rs (v0.8.37, lines 91-105):
let temp_dir = tempfile::tempdir()
.map_err(|e| ToolError::execution_failed(format!("tempdir failed: {e}")))?;
let script_path = temp_dir.path().join("js_execution.js");
tokio::fs::write(&script_path, code)
.await
.map_err(|e| ToolError::execution_failed(format!("tempfile write failed: {e}")))?;
let mut cmd = tokio::process::Command::new(&node);
cmd.arg(&script_path);
cmd.current_dir(workspace);
let output = tokio::time::timeout(Duration::from_secs(120), cmd.output())
.await
.map_err(|_| ToolError::Timeout { seconds: 120 })
.and_then(|res| res.map_err(|e| ToolError::execution_failed(e.to_string())))?;
The Command is built without cmd.env_clear() and without the project's crate::child_env::apply_to_tokio_command helper. Every variable in the parent process environment is inherited by the spawned node.
For comparison, exec_shell (crates/tui/src/tools/shell.rs:790-792) and the Python REPL (crates/tui/src/repl/runtime.rs:238) both apply the scrubber:
child_env::apply_to_command(&mut cmd, child_env::string_map_env(&exec_env.env));
apply_to_tokio_command calls cmd.env_clear() and then re-installs only the keys that pass is_allowed_parent_env_key (PATH, HOME, USER, LANG/LC_*, TMPDIR, proxy variables, Windows toolchain context, terminal settings). Secret-bearing variables (DEEPSEEK_API_KEY, OPENAI_API_KEY, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, GITHUB_TOKEN, etc.) are not on the allowlist and are dropped before the child starts. The js_execution path bypasses both the env_clear and the allowlist.
Commit history makes the gap explicit. Commit e6d4eae fix(security): scrub child process environments (2026-05-08) introduced child_env.rs and rewrote exec_shell, the Python REPL, the MCP launcher, and main.rs to use it. Commit 2566f3c feat(tools): add js_execution tool (2026-05-12) added this file four days later and never picked up the helper.
The tool is described to the model and surfaced in the approval pane as "Run model-provided JavaScript code in local Node.js execution sandbox" (crates/tui/src/core/engine/turn_loop.rs:1174-1176). No sandbox is applied beyond a 120-second timeout; Node has full filesystem and network access in addition to the inherited environment. The wording understates the trust boundary that the user is being asked to cross.
In YOLO mode (auto_approve=true) the JS body runs without any prompt at all, so a single adversarial prompt-injection from a README, fetched web page, or MCP server output drains the parent environment to the next model turn.
PoC
A standalone Cargo test reproduces the unscrubbed-env behavior. Save as crates/tui/tests/js_execution_env_leak.rs and run with cargo test -p deepseek-tui --test js_execution_env_leak -- --nocapture:
use deepseek_tui::tools::js_execution::execute_js_execution_tool;
use serde_json::json;
use tempfile::tempdir;
#[tokio::test]
async fn js_execution_inherits_parent_secrets() {
if deepseek_tui::dependencies::resolve_node().is_none() {
eprintln!("node not on PATH; skipping");
return;
}
unsafe {
…
- Record
GHSA-h539-c7r8-3xq4- CVSS 4.0
- 8.7 High
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-200, CWE-526
- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
deepseek-tuicrates.io |
0.8.32 to 0.8.41 | None known |
deepseek-tuinpm |
0.8.32 up to 0.8.41 | 0.8.41 |
codewhale-tuicrates.io |
0.8.41 up to 0.8.64 | 0.8.64 |
codewhalenpm |
0.8.41 up to 0.8.64 | 0.8.64 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-75915 is a high vulnerability (CVSS 8.7) in Hmbown Codewhale, published August 18, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.68%, the 52nd percentile. Fixed in deepseek-tui 0.8.41.
References
github.com/Hmbown/CodeWhale/security/advisories/GHSA-h539-c7r8-3xq4
github.com/Hmbown/CodeWhale/commit/26de44a8bd5051f8f944ea60b2c37ae1d2b7d25e
vulncheck.com/advisories/codewhale-before-environment-variable-leak-via-js-execution
nvd.nist.gov/vuln/detail/CVE-2026-75915
github.com/advisories/GHSA-h539-c7r8-3xq4
github.com/CVEProject/cvelistV5/tree/main/cves/2026/75xxx/CVE-2026-75915.json
github.com/Hmbown/CodeWhale
Left out here: the rest of 2 source descriptions. The JSON record has them.