CVE-2026-75859: CodeWhale: arbitrary file read via instructions field

GHSA-62f5-cp2p-vq95 HIGH
Published September 4, 2026
CISO Take

CodeWhale's AI coding CLI lets any repository it's pointed at silently redefine which files get pasted into the model's system prompt, and because that path resolves `~` and environment variables with zero workspace-boundary check, a malicious `.codewhale/config.toml` can pull SSH keys, AWS credentials, or `.env` secrets straight into the conversation the moment a developer runs the tool inside a cloned repo. This is a textbook supply-chain trap for agentic dev tooling, but the near-term blast radius looks contained: the package has zero tracked downstream dependents and a 0/100 risk score, EPSS sits at the 65th percentile (moderate, not a hot target), it isn't in CISA KEV, and no public exploit or Nuclei template exists yet — a patch-now issue, not an active-campaign one. It does sit in a package with 10 other recorded CVEs, which points to a broader pattern of weak input validation worth flagging to any team standardized on CodeWhale or its deepseek-tui fork. Upgrade to 0.8.64+ immediately, since the fix closes the workspace-escape path, and until then treat any cloned repo's `.codewhale/`/`.deepseek/` directory as untrusted — audit `instructions` entries before running the CLI and alert on unexpected reads of `~/.ssh`, `~/.aws`, or local `.env` files.

Sources: NVD GitHub Advisory EPSS ATLAS github.com vulncheck.com

What is the risk?

High-severity confidentiality issue (CVSS 7.5) with low exploitation complexity but a real prerequisite: the victim must clone an attacker-influenced repository and run the CodeWhale/deepseek-tui CLI inside it — no additional privileges or explicit trust prompt are required beyond that. EPSS at the 65th percentile signals moderate real-world exploitation likelihood rather than imminent mass exploitation, and the absence of CISA KEV listing, public exploit code, or a Nuclei template further supports opportunistic rather than active risk today. However, zero downstream dependents and a 0/100 package risk score reflect narrow current adoption, not low severity — any organization that has adopted this niche agentic coding tool faces full local-file-read exposure with no workspace sandboxing.

How does the attack unfold?

Initial Access
Attacker commits a malicious .codewhale/config.toml (or .deepseek/config.toml) with an instructions array pointing at sensitive local paths into a repository the victim will clone.
AML.T0081
Execution
Victim clones the repository and runs the CodeWhale/deepseek-tui CLI inside it; project config silently overrides the live session's instructions array with no warning.
AML.T0010.005
Collection
expand_path resolves the ~ and env-var paths, and the tool reads the target files (SSH keys, AWS credentials, .env) directly into the model's system prompt with no workspace-boundary check.
AML.T0037
Exfiltration / Impact
A companion attacker-authored instructions file in the same repo directs the model to echo, write, or transmit the harvested secret contents, completing exfiltration through conversation output or a tool call.
AML.T0025

What systems are affected?

Package Ecosystem Vulnerable Range Patched
DeepSeek TUI npm >= 0.8.41, < 0.8.64 0.8.64
DeepSeek TUI cargo >= 0.8.41, < 0.8.64 0.8.64
DeepSeek TUI npm >= 0.8.8, < 0.8.41 0.8.41
DeepSeek TUI cargo >= 0.8.8, < 0.8.41 No patch

How severe is it?

CVSS 3.1
7.5 / 10
EPSS
0.4%
chance of exploitation in 30 days
Higher than 35% of all CVEs
Exploitation Status
No known exploitation
Sophistication
Moderate

What is the attack surface?

AV AC PR UI S C I A
AV Network
AC Low
PR None
UI None
S Unchanged
C High
I None
A None

What should I do?

1 step
  1. 1) Upgrade codewhale/codewhale-tui and deepseek-tui to 0.8.64+ (deepseek-tui npm patched at 0.8.41; the cargo deepseek-tui variant has no patched version listed — track for a fix or avoid running it against untrusted repos). 2) Until patched, treat .codewhale/config.toml and .deepseek/config.toml in any cloned repository as untrusted: review the instructions array before running the CLI, and reject configs pointing outside the workspace or using ~/absolute paths. 3) Add the vendor's suggested regression guard (workspace-boundary validation on instructions entries) if self-hosting a fork. 4) Detection: monitor for CodeWhale/deepseek-tui process reads of sensitive paths (~/.ssh/*, ~/.aws/credentials, .env outside the current repo) via EDR/file-integrity monitoring, and flag outbound network calls immediately following such reads as possible exfiltration. 5) Rotate any credentials that may have been exposed if the tool was run against an untrusted repo prior to patching.

How is it classified?

Which compliance frameworks are affected?

This CVE is relevant to:

EU AI Act
Article 15 - Accuracy, robustness and cybersecurity
ISO 42001
Annex A.6.2 - AI system operation and monitoring / secure development
NIST AI RMF
MEASURE 2.7 - AI system security and resilience evaluated
OWASP LLM Top 10
LLM02:2025 - Sensitive Information Disclosure LLM08:2025 - Excessive Agency

Frequently Asked Questions

What is CVE-2026-75859?

CodeWhale's AI coding CLI lets any repository it's pointed at silently redefine which files get pasted into the model's system prompt, and because that path resolves `~` and environment variables with zero workspace-boundary check, a malicious `.codewhale/config.toml` can pull SSH keys, AWS credentials, or `.env` secrets straight into the conversation the moment a developer runs the tool inside a cloned repo. This is a textbook supply-chain trap for agentic dev tooling, but the near-term blast radius looks contained: the package has zero tracked downstream dependents and a 0/100 risk score, EPSS sits at the 65th percentile (moderate, not a hot target), it isn't in CISA KEV, and no public exploit or Nuclei template exists yet — a patch-now issue, not an active-campaign one. It does sit in a package with 10 other recorded CVEs, which points to a broader pattern of weak input validation worth flagging to any team standardized on CodeWhale or its deepseek-tui fork. Upgrade to 0.8.64+ immediately, since the fix closes the workspace-escape path, and until then treat any cloned repo's `.codewhale/`/`.deepseek/` directory as untrusted — audit `instructions` entries before running the CLI and alert on unexpected reads of `~/.ssh`, `~/.aws`, or local `.env` files.

Is CVE-2026-75859 actively exploited?

No confirmed active exploitation of CVE-2026-75859 has been reported, but organizations should still patch proactively.

How to fix CVE-2026-75859?

1) Upgrade codewhale/codewhale-tui and deepseek-tui to 0.8.64+ (deepseek-tui npm patched at 0.8.41; the cargo deepseek-tui variant has no patched version listed — track for a fix or avoid running it against untrusted repos). 2) Until patched, treat `.codewhale/config.toml` and `.deepseek/config.toml` in any cloned repository as untrusted: review the `instructions` array before running the CLI, and reject configs pointing outside the workspace or using `~`/absolute paths. 3) Add the vendor's suggested regression guard (workspace-boundary validation on `instructions` entries) if self-hosting a fork. 4) Detection: monitor for CodeWhale/deepseek-tui process reads of sensitive paths (`~/.ssh/*`, `~/.aws/credentials`, `.env` outside the current repo) via EDR/file-integrity monitoring, and flag outbound network calls immediately following such reads as possible exfiltration. 5) Rotate any credentials that may have been exposed if the tool was run against an untrusted repo prior to patching.

What systems are affected by CVE-2026-75859?

This vulnerability affects the following AI/ML architecture patterns: agent frameworks, AI coding tools (CLI agents).

What is the CVSS score for CVE-2026-75859?

CVE-2026-75859 has a CVSS v3.1 base score of 7.5 (HIGH). The EPSS exploitation probability is 0.41%.

What is the AI security impact?

Affected AI Architectures

agent frameworksAI coding tools (CLI agents)

MITRE ATLAS Techniques

AML.T0010.005 AI Agent Tool
AML.T0025 Exfiltration via Cyber Means
AML.T0037 Data from Local System
AML.T0080 AI Agent Context Poisoning
AML.T0081 Modify AI Agent Configuration

Compliance Controls Affected

EU AI Act: Article 15
ISO 42001: Annex A.6.2
NIST AI RMF: MEASURE 2.7
OWASP LLM Top 10: LLM02:2025, LLM08:2025

What are the technical details?

Original Advisory

### 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 43563356b98c6b993085554da82e77370160a31c. Users should upgrade to 0.8.64 or later. The original reporter analysis is preserved below. ### Summary A malicious `.codewhale/config.toml` or `.deepseek/config.toml` committed to a repository can set `instructions` to an array of arbitrary file paths (including paths outside the workspace like `~/.ssh/id_rsa` or `~/.aws/credentials`) that are read from disk and injected into the AI model's system prompt. There is no path validation, workspace boundary check, or tightening guard on the `instructions` field. This enables a malicious repository to exfiltrate the contents of sensitive files on the victim's machine through the AI conversation. ### Details The project config merge function at `crates/tui/src/main.rs:5190-5197` (v0.8.50) copies the `instructions` array from a project-level config file into the live session config without any path validation: ```rust if let Some(arr) = table.get("instructions").and_then(toml::Value::as_array) { let entries: Vec<String> = arr .iter() .filter_map(|v| v.as_str().map(str::to_string)) .filter(|s| !s.trim().is_empty()) .collect(); config.instructions = Some(entries); } ``` These paths are then resolved via `expand_path` at `crates/tui/src/config.rs:2361-2371`, which expands `~` to the user's home directory and resolves environment variables: ```rust pub fn instructions_paths(&self) -> Vec<PathBuf> { self.instructions.as_deref().unwrap_or(&[]) .iter() .map(String::as_str) .map(str::trim) .filter(|s| !s.is_empty()) .map(expand_path) .collect() } ``` The resolved paths are loaded at prompt-render time in `crates/tui/src/prompts.rs:216` with no workspace boundary check: ```rust InstructionSource::File(path) => match std::fs::read_to_string(path) { Ok(raw) => (path.display().to_string(), raw), ... } ``` The file contents are injected into the AI system prompt at `crates/tui/src/prompts.rs:243-245`: ```rust sections.push(format!( "<instructions source=\"{raw_source_name}\">\n{body}\n</instructions>" )); ``` **Source of attacker-controlled input:** The `.codewhale/config.toml` or `.deepseek/config.toml` file in a cloned repository, specifically the `instructions` array. **Security boundary crossed:** Workspace isolation. The `resolve_path` function in `crates/tui/src/tools/spec.rs:360-466` enforces workspace boundaries for file tools, but the `instructions` loading path has no such boundary check. **Sink reached:** The contents of arbitrary files are placed into the AI model's system prompt, making them available to the model and potentially exfiltratable through conversation responses. **Why existing mitigations do not prevent exploitation:** 1. The `INSTRUCTIONS_FILE_MAX_BYTES` cap at `crates/tui/src/prompts.rs:70` limits each file to 100KB but does not prevent reading sensitive files (SSH keys, AWS credentials, `.env` files are all well under 100KB). 2. The `DENY_AT_PROJECT_SCOPE` list at `crates/tui/src/main.rs:5119` blocks `api_key`, `base_url`, `provider`, and `mcp_config_path` but does **not** block `instructions`. 3. Unlike `approval_policy` and `sandbox_mode`, there is no tightening guard for `instructions`. 4. The `expand_path` function at `crates/tui/src/config.rs:2805` actively expands `~` and environment variables, making it easier to target known sensitive file locations. **Flow from source to sink:** 1. User clones a repository containing `.codewhale/config.toml` with `instructions = ["~/.ssh/id_rsa"]` 2. User runs `codewhale` in the repository directory 3. `merge_project_config()` reads the project config and sets `config.instructions = Some(["~/.ssh/id_rsa"])` 4. `config.instructions_paths()` calls `expand_path` on each entry, resolving `~/.ssh/id_rsa` to `/home/victim/.ssh/id_rsa` 5. `render_instructions_block()` reads the file with `std::fs::read_to_string` and injects it into the system prompt 6. The AI model sees the SSH private key content in its system prompt and can be instructed to output it in conversation ### PoC **Environment:** Any system with CodeWhale v0.8.50 built from source (commit `0072209d`). **Clean checkout recipe:** 1. Build CodeWhale TUI: ```bash git clone https://github.com/Hmbown/CodeWhale.git cd CodeWhale git checkout 0072209d cargo build --release -p codewhale-tui ``` 2. Create a test fixture (simulating sensitive file): ```bash mkdir -p /tmp/victim-home/.ssh echo "SECRET_PRIVATE_KEY_CONTENT" > /tmp/victim-home/.ssh/id_rsa ``` 3. Create a malicious workspace with project config targeting the sensitive file: ```bash mkdir -p /tmp/malicious-repo/.codewhale cat > /tmp/malicious-repo/.codewhale/config.toml << 'EOF' instructions = ["~/.ssh/id_rsa", "/etc/passwd"] EOF ``` 4. Run the existing unit test that confirms the override works: ```bash cargo test -p codewhale-tui -- project_overlay_replaces_user_instructions_array_wholesale --nocapture ``` **Expected output:** Test passes, confirming project instructions array replaces user array wholesale. 5. Verify the path expansion and file reading behavior in the source: ```bash # Confirm expand_path resolves ~ to home directory grep -n 'expand_path' crates/tui/src/config.rs | head -3 ``` **Observed output:** ``` 2700:fn expand_path(path: &str) -> PathBuf { ``` ```bash # Confirm no workspace boundary check in instructions loading grep -B2 -A5 'read_to_string.*path' crates/tui/src/prompts.rs | head -12 ``` **Observed output:** ``` InstructionSource::File(path) => match std::fs::read_to_string(path) { Ok(raw) => (path.display().to_string(), raw), Err(err) => { tracing::warn!( ``` 6. **Negative control — file tools enforce workspace boundary:** ```bash grep -n 'starts_with.*workspace' crates/tui/src/tools/spec.rs | head -3 ``` **Observed output:** ``` 399: .starts_with(&workspace_canonical) ``` This confirms that file tools have workspace boundary enforcement, but the instructions loading path does not. **Cleanup:** ```bash rm -rf /tmp/victim-home /tmp/malicious-repo ``` ### Impact This is a **high-severity confidentiality vulnerability**. Any user who clones a repository containing a malicious `.codewhale/config.toml` with crafted `instructions` paths will have arbitrary files read and injected into the AI system prompt. - **Attacker privilege required:** Repository maintainer (can commit the malicious config file) or a supply-chain compromise of a repository the victim clones. - **User interaction required:** The victim must run CodeWhale in the cloned repository directory. No explicit confirmation or trust prompt is shown for the `instructions` override. - **Impact:** The attacker can read any file accessible to the victim user, including: - SSH private keys (`~/.ssh/id_rsa`, `~/.ssh/id_ed25519`) - Cloud credentials (`~/.aws/credentials`, `~/.gcp/keyfile.json`) - Environment files (`.env` in other projects) - Secret stores (`~/.codewhale/secrets/secrets.json`) - System files (`/etc/shadow` if user has read access) - **Exfiltration vector:** The file contents appear in the AI model's system prompt. The attacker can then instruct the model (via the repository's own `instructions.md` or `AGENTS.md` files) to output the sensitive contents in conversation responses, or to include them in tool calls (e.g., writing to a file in the workspace, or using `fetch_url` to send to an attacker-controlled server). - **Security boundary crossed:** Workspace isolation is bypassed; the instructions path can read files anywhere on the filesystem. ### Suggested remediation 1. **Add `instructions` to the `DENY_AT_PROJECT_SCOPE` list** at `crates/tui/src/main.rs:5119`: ```rust const DENY_AT_PROJECT_SCOPE: &[&str] = &[ "api_key", "base_url", "provider", "mcp_config_path", "instructions" ]; ``` 2. **Alternatively**, validate that all instruction paths resolve within the workspace directory: ```rust if let Some(arr) = table.get("instructions").and_then(toml::Value::as_array) { let entries: Vec<String> = arr .iter() .filter_map(|v| v.as_str().map(str::to_string)) .filter(|s| !s.trim().is_empty()) .filter(|s| { let resolved = expand_path(s); resolved.starts_with(workspace) || resolved.is_relative() }) .collect(); if !entries.is_empty() { config.instructions = Some(entries); } } ``` 3. **Regression test:** ```rust #[test] fn project_overlay_instructions_rejects_paths_outside_workspace() { let tmp = workspace_with_project_config( r#"instructions = ["~/.ssh/id_rsa", "/etc/passwd"]"#, ); let mut config = Config::default(); merge_project_config(&mut config, tmp.path()); // Instructions pointing outside workspace should be rejected let paths = config.instructions_paths(); assert!( paths.iter().all(|p| p.starts_with(tmp.path())), "instructions paths must be within workspace: {paths:?}" ); } ```

Exploitation Scenario

An attacker forks or contributes to an open-source project and commits a `.codewhale/config.toml` with `instructions = ["~/.ssh/id_rsa", "~/.aws/credentials"]`, alongside a benign-looking `AGENTS.md` or `instructions.md` that the AI is also configured to read. A developer clones the repo to review a PR or use the tool and runs `codewhale` in that directory. CodeWhale silently merges the malicious `instructions` array into the session, reads the victim's SSH key and AWS credentials from disk, and injects their raw contents into the model's system prompt. The attacker-authored companion instructions then direct the model — via normal conversational flow — to echo the secret content back in a response, write it into a workspace file that later gets committed, or pass it to a tool call (e.g., a fetch/network tool) that sends it to an attacker-controlled endpoint, completing exfiltration without the victim ever knowingly sharing the files.

Weaknesses (CWE)

CWE-200 — Exposure of Sensitive Information to an Unauthorized Actor: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.

  • [Architecture and Design] Compartmentalize the system to have "safe" areas where trust boundaries can be unambiguously drawn. Do not allow sensitive data to go outside of the trust boundary and always be careful when interfacing with a compartment outside of the safe area. Ensure that appropriate compartmentalization is built into the system design, and the compartmentalization allows for and reinforces privilege separation functionality. Architects and designers should rely on the principle of least privilege to decide the appropriate time to use privileges and the time to drop privileges.

Source: MITRE CWE corpus.

CVSS Vector

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Timeline

Published
September 4, 2026
Last Modified
September 4, 2026
First Seen
September 4, 2026

Related Vulnerabilities