Summary
CodeWhale: Argument Injection in git_show Tool Allows Arbitrary File Write Without Approval
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.
Technical Details
Root Cause
crates/tui/src/tools/git_history.rs:
// 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.mdinstructs the model to callgit_showwithrevset 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()returnsAuto, no approval UI is shown. git show --output=<path>overwrites the target file with attacker-controlled commit metadata and diff text.
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 viacore.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).
CVE-2026-75913 has a CVSS score of 9.3 (High). The vector is network-reachable, no privileges required, and user interaction required. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (0.8.41, 0.8.64); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
Two changes in crates/tui/src/tools/git_history.rs:
Insert an end-of-options sentinel before rev so git stops parsing flags:
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):
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.
Frequently Asked Questions
- What is CVE-2026-75913? CVE-2026-75913 is a high-severity security vulnerability in deepseek-tui (rust), affecting versions >= 0.3.27, <= 0.8.41. It is fixed in 0.8.41, 0.8.64.
- How severe is CVE-2026-75913? CVE-2026-75913 has a CVSS score of 9.3 (High). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which packages are affected by CVE-2026-75913?
deepseek-tui(rust) (versions >= 0.3.27, <= 0.8.41)codewhale-tui(rust) (versions >= 0.8.41, < 0.8.64)codewhale(npm) (versions >= 0.8.41, < 0.8.64)
- Is there a fix for CVE-2026-75913? Yes. CVE-2026-75913 is fixed in 0.8.41, 0.8.64. Upgrade to this version or later.
- Is CVE-2026-75913 exploitable, and should I be worried? Whether CVE-2026-75913 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-75913 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-75913?
- Upgrade
deepseek-tuito 0.8.41 or later - Upgrade
codewhale-tuito 0.8.64 or later - Upgrade
codewhaleto 0.8.64 or later
- Upgrade