Loading...
Skip to main content

CVE-2026-75912 — CodeWhale: Argument Injection in deepseek-tui —...

HIGH

CodeWhale: Argument Injection in `git_blame` Tool Allows Arbitrary File Read Without Approval

Published September 4, 2026Updated September 4, 2026Source: osv

Summary

### 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 9a34b5034d29f05d1f28fa61b04719ca6a741020. Users should upgrade to 0.8.64 or later. The original reporter analysis is preserved below. # Argument Injection in `git_blame` Tool Allows Arbitrary File Read Without Approval ## Overview The `git_blame` tool in DeepSeek-TUI passes the model-supplied `rev` parameter unvalidated into the argv of `git blame`. `git blame` accepts `--contents=<file>`, which causes it to use the file's contents in place of the working tree and echo each line verbatim in the blame output. A `rev` value of `--contents=/path/to/secret` therefore exfiltrates the targeted file's contents into the tool result, which is returned to the model and displayed in the chat transcript. The tool is registered with `ApprovalRequirement::Auto` and declares `ToolCapability::ReadOnly`. The read is in-scope for the capability label, but the *target* of the read is not the user expects `git_blame` to read files inside the workspace, not arbitrary paths on the host. This is a sibling of the `git_show` argument-injection vulnerability filed separately, sharing the same root cause (missing `--end-of-options` sentinel and unvalidated `rev`). ## Impact Arbitrary file read at the privilege of the user running DeepSeek-TUI, via malicious repository content combined with prompt injection (the threat model already documented in CVE-2026-45311). Reachable as the invoking user: - `~/.ssh/id_rsa`, `~/.ssh/id_ed25519`, and other private keys - `~/.aws/credentials`, `~/.config/gh/hosts.yml`, `~/.netrc` - `.env` files anywhere in the filesystem - Any project file outside the workspace the tool would normally restrict to The leaked contents land in the model's context. The same model that obeyed the prompt-injection in step one can be instructed to forward the leak via `fetch_url` (network-policy permitting), summarize it in chat, or write it into a tool output the attacker can later retrieve. ## Technical Details ### Root Cause `crates/tui/src/tools/git_history.rs`: ```rust // L314-316 fn approval_requirement(&self) -> ApprovalRequirement { ApprovalRequirement::Auto } // L322-358 (excerpt) async fn execute(&self, input: Value, context: &ToolContext) -> Result<ToolResult, ToolError> { let path_str = required_str(&input, "path")?; let resolved_path = context.resolve_path(path_str)?; // path is bounded to workspace ... let rev = optional_str(&input, "rev").unwrap_or("HEAD"); // rev is NOT bounded ... let mut args = vec![ "blame".to_string(), "--date=iso".to_string(), format!("-L{start_line},{end_line}"), ]; if porcelain { args.push("--line-porcelain".to_string()); } args.push(rev.to_string()); // unvalidated, no sentinel args.push("--".to_string()); args.push(pathspec.display().to_string()); ... } ``` `path` correctly flows through `context.resolve_path`, which enforces workspace containment (`spec.rs:342`). `rev` does not and the `--` separator after `rev` only ends pathspec parsing, it does not stop option parsing of `rev` itself. The JSON schema for `rev` (L283-285) is `{"type": "string"}` with no constraints. ### Why `--contents` Works `git blame --contents=<file> -- <pathspec>` blames the working tree path *as if its contents were the supplied file*. Each line of the supplied file appears verbatim in the porcelain or human-readable output, prefixed with the attribution marker `00000000 (External file (--contents) <date> N)`. The full line content is preserved. Two secondary primitives in the same parser also leak data, with smaller yield: - `--ignore-revs-file=<file>` : surfaces parse errors that disclose partial content when the file is not a valid revs list. - `-S <file>`, `--reverse <rev1>..<rev2>` : not directly exploitable for read but expand the option surface that argv injection can reach. ## Proof of Concept Argv assembled by the tool with input `{"path": "a.txt", "rev": "--contents=/home/a/.ssh/id_rsa"}`: ``` git blame --date=iso -L1,200 --contents=/home/a/.ssh/id_rsa -- a.txt ``` Reproduced against system `git` as a non-root user: ``` $ id uid=1001(a) gid=1001(a) groups=1001(a) $ echo "PRIVATEKEYDATA" > /home/a/.ssh/id_rsa $ chmod 600 /home/a/.ssh/id_rsa $ git blame --date=iso -L1,5 "--contents=/home/a/.ssh/id_rsa" -- a.txt 00000000 (External file (--contents) 2026-05-19 07:05:51 -0400 1) PRIVATEKEYDATA ``` A non-readable target (`/etc/shadow`, owned by root with mode 0640) returns `Permission denied`, confirming the read is bounded by uid as expected; this is not a privilege boundary bypass, it is the desktop user's own filesystem view being exposed past the workspace boundary the tool's `path` argument otherwise enforces. End-to-end exploitation is identical to the `git_show` companion: malicious repo → `AGENTS.md` injection → model calls `git_blame` with the crafted `rev` → auto-approval → leaked content returned in tool output and consumed by the model. ## Remediation Same shape as the `git_show` fix: ```rust args.push("--end-of-options".to_string()); args.push(rev.to_string()); args.push("--".to_string()); args.push(pathspec.display().to_string()); ``` Plus a leading-hyphen rejection on `rev`. A regression test should pin both `rev = "--contents=/etc/passwd"` and `rev = "--ignore-revs-file=/etc/passwd"` as rejected inputs.

Advisory Timeline

  • First published September 4, 2026 (38 days ago).
  • Last revised September 4, 2026 — 0 days after initial publication.

Remediation

Upgrade to the fixed version using your package manager.

npm
Update deepseek-tui to 0.8.41 or later
npm install deepseek-tui@0.8.41
npm
Update codewhale to 0.8.64 or later
npm install codewhale@0.8.64
Cargo
Update codewhale-tui to 0.8.64 or later
cargo update -p codewhale-tui --precise 0.8.64

After upgrading, run your dependency scanner again to confirm the vulnerability is resolved.

Affected Packages (4)

Affects 2 ecosystems: crates.io (2), npm (2).

PackageEcosystemAffectedFixed In
deepseek-tui
npm
All versions0.8.41
codewhale
npm
All versions0.8.64
deepseek-tui
crates.io
All versionsRange-based data available
codewhale-tui
crates.io
All versions0.8.64

Vulnerability Classification

Common Weakness Enumeration (CWE) identifiers for this vulnerability type.

CVSS Score Breakdown

What the CVSS (Common Vulnerability Scoring System) 7.4 score means for each attack dimension.

Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
Required
Scope
Changed
Confidentiality
High
Integrity
None
Availability
None

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

Frequently Asked Questions

What is CVE-2026-75912?
CodeWhale: Argument Injection in `git_blame` Tool Allows Arbitrary File Read Without Approval This vulnerability has been assigned a severity rating of HIGH (CVSS score: 7.4/10).
How do I check if my project is affected by CVE-2026-75912?
CVE-2026-75912 affects deepseek-tui, codewhale and codewhale-tui. Use GeekWala's free vulnerability scanner to check your dependencies against CVE-2026-75912 and 200,000+ other known vulnerabilities.

Severity & Exploitability

CVSS Score
7.4

High exploitability or significant impact. Prioritize remediation within days.

Also Known As

GHSA-c6mw-8xh8-gpq6

Related CVEs

  • CVE-2026-75856
    CRITICAL

    CodeWhale: SSRF bypass - TOCTOU on DNS failure for DNS pinning

  • CVE-2026-75859
    HIGH

    CodeWhale: Project config `instructions` override enables arbitrary file read into AI system prompt via cloned repository

  • CVE-2026-75913
    HIGH

    CodeWhale: Argument Injection in `git_show` Tool Allows Arbitrary File Write Without Approval

  • CVE-2026-75857
    HIGH

    CodeWhale: exec_shell_interact sends LLM-controlled input to a running shell without an approval prompt (privilege escalation)

  • CVE-2026-75911
    HIGH

    CodeWhale: Project config `allow_shell` override enables arbitrary shell command execution via cloned repository

  • CVE-2026-75915
    HIGH

    CodeWhale: js_execution leaks parent environment to model context via missing env scrub

  • CVE-2026-75914
    HIGH

    CodeWhale: image_analyze follows workspace symlinks, leaking external file bytes

  • CVE-2026-75858
    HIGH

    CodeWhale: rlm_eval auto-approves arbitrary Python execution, bypassing the user's approval policy (RCE)

Check if you're affected

Scan your dependencies to see if this vulnerability affects your projects.

Scan Your Dependencies