Loading...
Skip to main content

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

HIGH

CodeWhale: Argument Injection in `git_show` Tool Allows Arbitrary File Write 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_show` Tool Allows Arbitrary File Write Without Approval ## Overview The `git_show` tool in DeepSeek-TUI executes `git show` with the model-supplied `rev` parameter passed unvalidated into the argv. `git show` honours the `--output=<path>` option, so a `rev` value beginning with `--output=` is interpreted as a flag rather than a revision. The tool is registered with `ApprovalRequirement::Auto` and declares `ToolCapability::ReadOnly`, so the write happens without a user prompt and contradicts the capability the catalog advertises to the model and the user. This is the same vulnerability class as GHSA-72w5-pf8h-xfp4 (CVE-2026-45374): an auto-approved tool produces an effect outside the boundary the user consented to. ## Impact A malicious repository combined with prompt injection, the threat model already documented in CVE-2026-45311 (auto-loaded `AGENTS.md` is treated as instructions by the model) yields an unprompted arbitrary file write at the privilege of the user running DeepSeek-TUI. Useful targets reachable as the invoking user: - `~/.ssh/authorized_keys` - `~/.bashrc`, `~/.zshrc`, `~/.profile` - `~/.gitconfig` (chainable into RCE via `core.editor`) - `~/.config/**`, `~/.aws/credentials`, project source files The written content is the `git show` rendering of HEAD commit hash, author/date header, indented commit message, and (when `patch=true`) diff hunks. The commit subject, body, author identity, and diff text are entirely attacker-controlled because the attacker owns the repository HEAD. The leading `commit <hash>` line prevents clean overwrite of formats that reject unknown tokens, but is silently ignorable in files parsed as comments-or-text (crontab, dotfiles consumed by tolerant readers) and is irrelevant for the destructive/DoS sub-case (clobbering `~/.ssh/authorized_keys` locks the user out; clobbering a project file corrupts source). ## Technical Details ### Root Cause `crates/tui/src/tools/git_history.rs`: ```rust // L196-198 fn approval_requirement(&self) -> ApprovalRequirement { ApprovalRequirement::Auto } // L204-228 (excerpt) async fn execute(&self, input: Value, context: &ToolContext) -> Result<ToolResult, ToolError> { let rev = required_str(&input, "rev")?; ... let mut args = vec![ "show".to_string(), "--no-color".to_string(), "--no-ext-diff".to_string(), ]; if patch { args.push(format!("--unified={unified}")); } else { args.push("--no-patch".to_string()); } if stat { args.push("--stat".to_string()); } args.push(rev.to_string()); // unvalidated, no `--end-of-options` sentinel ... } ``` The JSON schema for `rev` is `{"type": "string"}` (L161-164) with no `pattern`, no enum, and no length cap. `required_str` performs no semantic validation. The argv has no `--end-of-options` separator between the trailing options and `rev`, so git's option parser keeps consuming flags from `rev`. The same pattern in `git_blame` (L322-388) is tracked in a separate advisory. ### Why `--output` Works `git show` shares its option parser with `git log` / `git diff`, which expose `--output=<file>`. The implementation opens the path with `O_WRONLY | O_CREAT | O_TRUNC` and writes the formatted output there. No permission check beyond the filesystem's own running as the user is sufficient to clobber anything the user owns. ## Proof of Concept The vulnerable argv assembled by the tool when invoked with `{"rev": "--output=/home/victim/.bashrc"}` is equivalent to: ``` git show --no-color --no-ext-diff --no-patch --stat --output=/home/victim/.bashrc ``` Reproduced against system `git` as a non-root user: ``` $ id uid=1001(lowtest) gid=1001(lowtest) groups=1001(lowtest) $ cd /tmp/lp && git init -q $ echo a > a.txt && git add a.txt $ git -c user.email=a@b -c user.name=a commit -q -m "lol" $ git show --no-color --no-patch "--output=/home/lowtest/.bashrc_clobbered" HEAD $ ls -la /home/lowtest/.bashrc_clobbered -rw-rw-r-- 1 lowtest lowtest 128 May 19 07:05 /home/lowtest/.bashrc_clobbered ``` End-to-end exploitation path: - Attacker publishes a repository whose `AGENTS.md` instructs the model to call `git_show` with `rev` set to a crafted `--output=` string targeting a file in the victim's home directory. The same auto-load pathway documented in CVE-2026-45311 applies. - Victim opens the repository in DeepSeek-TUI and issues any prompt that exercises the agent loop. - The model issues the tool call. Because `approval_requirement()` returns `Auto`, no approval UI is shown. - `git show --output=<path>` overwrites the target file with attacker-controlled commit metadata and diff text. ## Remediation Two changes in `crates/tui/src/tools/git_history.rs`: Insert an end-of-options sentinel before `rev` so git stops parsing flags: ```rust args.push("--end-of-options".to_string()); args.push(rev.to_string()); ``` Reject `rev` values that begin with `-` (or restrict to a revision-shape regex `^[A-Za-z0-9._/^~@:{}-]+$` after the leading character check): ```rust if rev.starts_with('-') { return Err(ToolError::invalid_input("rev must not start with '-'")); } ``` A regression test mirroring `run_tests_requires_user_approval` (`test_runner.rs:197`) should assert that `rev = "--output=/tmp/x"` is rejected.

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) 9.3 score means for each attack dimension.

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

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

Frequently Asked Questions

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

Severity & Exploitability

CVSS Score
9.3

Exploitation is straightforward and causes maximum impact. Patch immediately.

Also Known As

GHSA-7j5w-7r7x-9v27

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-75912
    HIGH

    CodeWhale: Argument Injection in `git_blame` Tool Allows Arbitrary File Read 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