CVE-2026-75913: CodeWhale Argument Injection Vulnerability

HIGH
Advisory Identifier: GHSA-7j5w-7r7x-9v27
CVSS 9.3
CWE-88 CWE-73
Published
Advisory Summary

CVE-2026-75913 is a HIGH (CVSS 9.3) argument injection vulnerability (CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')) affecting CodeWhale libraries in the crates.io ecosystem. The issue involves argument injection in `git_show` tool allows arbitrary file write without approval. Remediation is available by upgrading affected packages to version 0.8.41, 0.8.64.

CVE-2026-75913 at a Glance

CVE Identifier CVE-2026-75913
GHSA Identifier GHSA-7j5w-7r7x-9v27
Severity HIGH
CVSS v3.1 Base Score 9.3
CWE Classification CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')
Affected Product CodeWhale
Package Ecosystem crates.io
Published Date
Last Updated

Security Impact

CVSS: 9.3

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required None (PR:N)
User Interaction Required (UI:R)
Scope Changed (S:C)
Confidentiality None (C:N)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-75913

To remediate this vulnerability, upgrade all affected CodeWhale dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

deepseek-tui fixed: Latest secure release
Upgrade deepseek-tui to Latest secure release
deepseek-tui fixed: 0.8.41
npm install deepseek-tui@0.8.41
codewhale-tui fixed: 0.8.64
Upgrade codewhale-tui to 0.8.64
codewhale fixed: 0.8.64
npm install codewhale@0.8.64
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for deepseek-tui

How to Check if You Are Affected

To determine whether your application is affected by CVE-2026-75913, inspect your project dependencies for CodeWhale:

inspect dependencies for deepseek-tui

Analyze the terminal output to locate any version of CodeWhale in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.8.41), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection'), where the product constructs a string for a command to be executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string. In CodeWhale, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

### 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.

CVE-2026-75913 Affected CodeWhale Versions

4 component(s)
Fixed Versions:
0.8.410.8.64
Product / Package Ecosystem Affected Versions Fixed Version
deepseek-tui
crates.io
≥ 0.3.27
≤ 0.8.41
deepseek-tui
npm
≥ 0.3.27
< 0.8.41
0.8.41
codewhale-tui
crates.io
≥ 0.8.41
< 0.8.64
0.8.64
codewhale
npm
≥ 0.8.41
< 0.8.64
0.8.64

References

Frequently Asked Questions

What is CVE-2026-75913?
CVE-2026-75913 is a security vulnerability in CodeWhale involving Argument Injection in `git_show` Tool Allows Arbitrary File Write Without Approval under CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection').
Which CodeWhale versions are affected?
Affected versions include releases prior to 0.8.41, 0.8.64 across affected packages: deepseek-tui, codewhale-tui, codewhale.
What version fixes CVE-2026-75913?
Upgrading to 0.8.41, 0.8.64 (or the latest patched release for your respective branch) resolves the vulnerability.
Is deepseek-tui affected?
Yes, deepseek-tui is affected in releases prior to Latest secure release, 0.8.41. Upgrade your dependency to Latest secure release, 0.8.41 or later.
Is codewhale-tui affected?
Yes, codewhale-tui is affected in releases prior to 0.8.64. Upgrade your dependency to 0.8.64 or later.
What is the CVSS score of CVE-2026-75913?
CVE-2026-75913 has a CVSS v3.1 base score of 9.3 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:H.
What CWE is associated with CVE-2026-75913?
CVE-2026-75913 is classified under CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') (The product constructs a string for a command to be executed by a separate component in another control sphere, but it does not properly delimit the intended arguments, options, or switches within that command string.).
How can I check crates.io dependencies for CVE-2026-75913?
Run the dependency tree command: 'inspect dependencies for deepseek-tui'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-7j5w-7r7x-9v27",
  "modified" : "2026-09-04T18:02:37Z",
  "published" : "2026-09-04T18:02:37Z",
  "aliases" : [ "CVE-2026-75913" ],
  "summary" : "CodeWhale: Argument Injection in `git_show` Tool Allows Arbitrary File Write Without Approval",
  "details" : "### Maintainer resolution\n\nThe 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.\n\n# Argument Injection in `git_show` Tool Allows Arbitrary File Write Without Approval\n\n## Overview\n\nThe `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.\n\nThis 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.\n\n## Impact\n\nA 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.\n\nUseful targets reachable as the invoking user:\n\n- `~/.ssh/authorized_keys`\n- `~/.bashrc`, `~/.zshrc`, `~/.profile`\n- `~/.gitconfig` (chainable into RCE via `core.editor`)\n- `~/.config/**`, `~/.aws/credentials`, project source files\n\nThe 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).\n\n## Technical Details\n\n### Root Cause\n\n`crates/tui/src/tools/git_history.rs`:\n\n```rust\n// L196-198\nfn approval_requirement(&self) -> ApprovalRequirement {\n    ApprovalRequirement::Auto\n}\n\n// L204-228 (excerpt)\nasync fn execute(&self, input: Value, context: &ToolContext) -> Result<ToolResult, ToolError> {\n    let rev = required_str(&input, \"rev\")?;\n    ...\n    let mut args = vec![\n        \"show\".to_string(),\n        \"--no-color\".to_string(),\n        \"--no-ext-diff\".to_string(),\n    ];\n    if patch { args.push(format!(\"--unified={unified}\")); }\n    else     { args.push(\"--no-patch\".to_string()); }\n    if stat  { args.push(\"--stat\".to_string()); }\n    args.push(rev.to_string());        // unvalidated, no `--end-of-options` sentinel\n    ...\n}\n```\n\nThe 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`.\n\nThe same pattern in `git_blame` (L322-388) is tracked in a separate advisory.\n\n### Why `--output` Works\n\n`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.\n\n## Proof of Concept\n\nThe vulnerable argv assembled by the tool when invoked with\n`{\"rev\": \"--output=/home/victim/.bashrc\"}` is equivalent to:\n\n```\ngit show --no-color --no-ext-diff --no-patch --stat --output=/home/victim/.bashrc\n```\n\nReproduced against system `git` as a non-root user:\n\n```\n$ id\nuid=1001(lowtest) gid=1001(lowtest) groups=1001(lowtest)\n\n$ cd /tmp/lp && git init -q\n$ echo a > a.txt && git add a.txt\n$ git -c user.email=a@b -c user.name=a commit -q -m \"lol\"\n\n$ git show --no-color --no-patch \"--output=/home/lowtest/.bashrc_clobbered\" HEAD\n$ ls -la /home/lowtest/.bashrc_clobbered\n-rw-rw-r-- 1 lowtest lowtest 128 May 19 07:05 /home/lowtest/.bashrc_clobbered\n```\n\nEnd-to-end exploitation path:\n\n- 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.\n- Victim opens the repository in DeepSeek-TUI and issues any prompt that exercises the agent loop.\n- The model issues the tool call. Because `approval_requirement()` returns `Auto`, no approval UI is shown.\n- `git show --output=<path>` overwrites the target file with attacker-controlled commit metadata and diff text.\n\n## Remediation\n\nTwo changes in `crates/tui/src/tools/git_history.rs`:\n\nInsert an end-of-options sentinel before `rev` so git stops parsing flags:\n\n   ```rust\n   args.push(\"--end-of-options\".to_string());\n   args.push(rev.to_string());\n   ```\n\nReject `rev` values that begin with `-` (or restrict to a revision-shape\n   regex `^[A-Za-z0-9._/^~@:{}-]+$` after the leading character check):\n\n   ```rust\n   if rev.starts_with('-') {\n       return Err(ToolError::invalid_input(\"rev must not start with '-'\"));\n   }\n   ```\n\nA regression test mirroring `run_tests_requires_user_approval` (`test_runner.rs:197`) should assert that `rev = \"--output=/tmp/x\"` is rejected.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:H"
  }, {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:H/VA:H/SC:N/SI:H/SA:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "crates.io",
      "name" : "deepseek-tui"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.3.27"
      }, {
        "last_affected" : "0.8.41"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "npm",
      "name" : "deepseek-tui"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.3.27"
      }, {
        "fixed" : "0.8.41"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "crates.io",
      "name" : "codewhale-tui"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.8.41"
      }, {
        "fixed" : "0.8.64"
      } ]
    } ]
  }, {
    "package" : {
      "ecosystem" : "npm",
      "name" : "codewhale"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0.8.41"
      }, {
        "fixed" : "0.8.64"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/Hmbown/CodeWhale/security/advisories/GHSA-7j5w-7r7x-9v27"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-75913"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/Hmbown/CodeWhale/commit/9a34b5034d29f05d1f28fa61b04719ca6a741020"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/Hmbown/CodeWhale"
  }, {
    "type" : "WEB",
    "url" : "https://www.vulncheck.com/advisories/codewhale-before-argument-injection-via-git-show"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-73", "CWE-88" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-09-04T18:02:37Z",
    "nvd_published_at" : "2026-08-18T16:18:23Z"
  }
}