Alta

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

  • Publicada: 04.09.2026
  • Actualizado: 11.10.2026 10:22

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:

bash
git show --no-color --no-ext-diff --no-patch --stat --output=/home/victim/.bashrc

Reproduced against system git as a non-root user:

bash
$ 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.

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm codewhale >= 0.8.41, < 0.8.64 0.8.64
Paquete de npm deepseek-tui >= 0.3.27, < 0.8.41 0.8.41

Referencias

Puntuación CVSS 9.3/10
Vector CVSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:N/I:H/A:H
Debilidad (CWE)
CWE-73, CWE-88
Plataforma
npm
Paquete
codewhale, deepseek-tui
Publicada
04.09.2026
Actualizado
11.10.2026 10:22

Fuentes y licencias

OSV / GitHub Advisory Database - GHSA-7j5w-7r7x-9v27 - CC BY 4.0

Historial de vulnerabilidades: deepseek-tui

Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (11) en el archivo
Entradas en total
11
Primera → última
05.2026 09.2026
Sin corrección
0
Explotada en ataques
0

Distribución por gravedad

  • Crítica 2
  • Alta 9

Divulgaciones por año

  1. 2026: 11
Gravedad:
  1. Crítica · 8.6 CVE-2026-75856 >= 0.8.5, < 0.8.41 0.8.41
  2. CodeWhale: Argument Injection in `git_show` Tool Allows Arbitrary File Write Without Approval esta entrada
    Alta · 9.3 CVE-2026-75913 >= 0.3.27, < 0.8.41 0.8.41
  3. Alta · 7.5 CVE-2026-75914 >= 0.8.32, < 0.8.41 0.8.41
  4. Crítica · 9.6 CVE-2026-45311 >= 0.3.0, < 0.8.23 0.8.23
  5. Alta · 7.4 CVE-2026-45310 < 0.8.22 0.8.22

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.