# PIR-2026-0057 - CodeWhale coding agent: a cloned repository silently takes over the agent - project-config overrides grant shell and inject files into the system prompt, and two git tools take unvalidated arguments to read and write arbitrary files, all past the approval gate

- `id`: PIR-2026-0057
- `title`: CodeWhale (an AI coding-agent TUI, formerly deepseek-tui) trusts repository-controlled input it should treat as hostile. A malicious `.codewhale/config.toml`/`.deepseek/config.toml` committed to a cloned repo can silently set `allow_shell = true` (arbitrary shell execution) or point `instructions` at arbitrary files that are read into the model's system prompt; separately, the `git_blame` and `git_show` tools pass an unvalidated revision argument straight to git, so `--contents=` reads and `--output=` writes arbitrary files - and all four tools run under `ApprovalRequirement::Auto`, so none of it prompts the user. Four coordinated CVEs (CVE-2026-75911, -75859, -75912, -75913), all fixed in 0.8.64
- `date_occurred`: not applicable - vulnerability disclosure (no confirmed in-the-wild exploitation tied to these CVEs)
- `date_detected`: coordinated disclosure to the CodeWhale maintainers; no individual discoverer is credited in the GitHub advisories
- `date_disclosed`: 2026-07-16 (the four GitHub Security Advisories were published 2026-07-16; the advisories were reviewed/updated 2026-09-04, which is when the leads surfaced)
- `status`: corroborated (all four GitHub Security Advisories - GHSA-gx45-xrj5-g6c4, GHSA-62f5-cp2p-vq95, GHSA-c6mw-8xh8-gpq6, GHSA-7j5w-7r7x-9v27 - read 2026-09-09; product, affected/fixed versions, mechanism, CVSS and CVE ids confirmed)

### The agent
- `agent_description`: CodeWhale, an AI coding-agent TUI (terminal user interface) that drives a large language model to read, edit and run code in a developer's local workspace with a set of built-in tools (shell, and git tools including `git_blame` and `git_show`). It was previously published as `deepseek-tui` and renamed; both names are affected. Distributed as npm `codewhale` and cargo `codewhale-tui` (and the older npm/cargo `deepseek-tui`).
- `operator_type`: individual developers running the agent locally against repositories they clone (affects any deployment on an affected version; the flaw is in the agent, not one operator's configuration)
- `autonomy_level`: human-on-the-loop by design (a developer supervises the coding session) - but the point of these CVEs is that the affected actions run under `ApprovalRequirement::Auto`, so the human-in-the-loop is bypassed for exactly the dangerous operations
- `model_stack`: DeepSeek models by default; model-agnostic to the flaw - the defects are in the agent harness (config loader and tool layer), not in the model
- `harness`: CodeWhale / codewhale-tui; formerly deepseek-tui. Affected: codewhale (npm) and codewhale-tui (cargo) >= 0.8.41 and < 0.8.64; deepseek-tui affected in earlier ranges (npm >= 0.3.27 to 0.8.6-era depending on CVE, < 0.8.41). Fixed in 0.8.64 (the cargo `deepseek-tui` line has no patch - superseded by codewhale)

### Authority
- `authority_scope`: full local compromise of the developer's machine reachable from merely opening a hostile repository in the agent - arbitrary shell command execution (config `allow_shell` override), arbitrary file read (git_blame `--contents=`, and the `instructions` override reading files into the prompt), and arbitrary file write (git_show `--output=`). Read targets explicitly include SSH keys, AWS credentials and environment files
- `funds_at_risk_usd`: unknown
- `blast_radius`: one developer workstation per hostile repository opened; a path to wider compromise if the developer's exfiltrated credentials or the arbitrary-write primitive enable lateral movement or supply-chain push access (potential, not realized in these disclosures)

### The failure
- `root_cause`: tool-error (the agent's tool and config layer trusts repository-controlled input it should treat as untrusted, and does not enforce its own approval/capability contract: a committed config file can grant shell or redirect `instructions`, and two git tools concatenate an unvalidated revision argument into the git command line while declaring `ApprovalRequirement::Auto` - git_show even declares `ToolCapability::ReadOnly` yet writes files). One of the four (the `instructions` override, CVE-2026-75859) is also prompt-injection-class - repo content injected into the system prompt - and the git-tool abuses are reached via prompt injection on a malicious repo; recorded under tool-error because the enforceable defect is in the harness's tool/config implementation. See the schema note.
- `failure_locus`: harness (the agent application's own config loader and built-in git tools; not an MCP server and not the model's reasoning)
- `exploitation_status`: researcher-demonstrated (four CVEs assigned and mechanisms publicly described with the exploit primitives; no confirmed in-the-wild exploitation tied to these identifiers)
- `mechanism`: Four related weaknesses, all triggered by a repository the developer clones and opens in the agent, all running without an approval prompt. (1) CVE-2026-75911 (CVSS 8.5): a malicious `.codewhale/config.toml` or `.deepseek/config.toml` committed to the repo can set `allow_shell = true`, silently flipping the default-off shell boundary so the model can execute arbitrary shell commands. (2) CVE-2026-75859 (CVSS 8.7): the same config's `instructions` field accepts an array of arbitrary file paths that are read from disk with no workspace-boundary check and injected into the model's system prompt - exposing SSH keys, cloud credentials and env files where they become exfiltrable. (3) CVE-2026-75912 (CVSS 8.3): the `git_blame` tool passes its `rev` parameter to git unvalidated, so a value like `--contents=/path/to/secret` turns a blame into an arbitrary file read; the tool is registered `ApprovalRequirement::Auto`, so no consent is sought. (4) CVE-2026-75913 (CVSS 8.5): the `git_show` tool likewise passes `rev` unvalidated, so `--output=/path` writes an attacker-chosen file - an arbitrary file write that also contradicts the tool's declared `ToolCapability::ReadOnly`. The unifying error is that repository-controlled configuration and tool arguments are trusted, and the agent's own approval/read-only contract is not enforced for the operations that most need it.
- `adversary_present`: no (disclosed vulnerabilities; the threat model is a malicious repository author, but no in-the-wild adversary is tied to these CVEs)

### Impact
- `severity`: near-miss (the full capability is exposed - remote-ish code execution, arbitrary file read/write, secret exfiltration from cloning one hostile repo - but no realized loss is reported for these CVEs, and all four are patched in 0.8.64)
- `direct_loss_usd`: 0 (no confirmed exploitation or loss)
- `indirect_loss_usd`: unknown
- `downtime`: none
- `data_exposure`: none confirmed; the exposed capability is reading arbitrary local files (SSH keys, AWS credentials, environment files) into the model prompt and off the machine, plus arbitrary file write

### Detection and recovery
- `detected_by`: third-party (security research / coordinated disclosure; no individual discoverer credited in the advisories)
- `time_to_detect`: unknown
- `time_to_recover`: fixed in CodeWhale 0.8.64
- `remediation`: upgrade to codewhale / codewhale-tui >= 0.8.64. The fixed version validates the revision argument to git tools, enforces the workspace boundary and approval contract, and no longer honours a repository-committed config that silently grants shell or redirects `instructions`
- `structural_fix`: an agent-harness lesson, not a single-CVE patch: repository-controlled input (project config AND tool arguments) is untrusted input and must be validated and boundary-checked; a tool's declared approval requirement and read-only capability must be ENFORCED, not merely declared; and privilege-granting configuration (shell enablement, prompt `instructions`) must never be settable by a cloned repo without explicit user consent. The "open a repo in your coding agent" action is a trust boundary
- `controls_that_worked`: none identified - the default shell-off boundary was defeated by the config override, and the Auto-approval tools bypassed the human-on-the-loop entirely

### Evidence
- `telemetry_grade`: none (coordinated vulnerability disclosure, not an operated incident with logs)
- `sources`:
  - https://github.com/advisories/GHSA-gx45-xrj5-g6c4 (CVE-2026-75911, CVSS 8.5: `.codewhale`/`.deepseek` config `allow_shell` override -> arbitrary shell execution; affected codewhale/codewhale-tui >= 0.8.41 < 0.8.64, fixed 0.8.64; read 2026-09-09)
  - https://github.com/advisories/GHSA-62f5-cp2p-vq95 (CVE-2026-75859, CVSS 8.7: config `instructions` reads arbitrary file paths into the AI system prompt, no workspace-boundary check; fixed 0.8.64; read 2026-09-09)
  - https://github.com/advisories/GHSA-c6mw-8xh8-gpq6 (CVE-2026-75912, CVSS 8.3: `git_blame` argument injection via unvalidated `rev` (`--contents=`) -> arbitrary file read without approval, tool registered ApprovalRequirement::Auto; fixed 0.8.64; read 2026-09-09)
  - https://github.com/advisories/GHSA-7j5w-7r7x-9v27 (CVE-2026-75913, CVSS 8.5: `git_show` argument injection via unvalidated `rev` (`--output=`) -> arbitrary file write without approval, contradicting declared ToolCapability::ReadOnly; fixed 0.8.64; read 2026-09-09)
  - `independence`: low-to-medium - all four are GitHub Security Advisories for the same product from one coordinated disclosure; they corroborate each other on product, versions and fixed release, but are not four independent operators. No independent second report, as expected for a disclosed vulnerability rather than an operated incident
- `related`: PIR-2026-0056 (Grafana MCP SSRF), PIR-2026-0026 (GitHub MCP toxic-agent flow), PIR-2026-0028 (Supabase MCP lethal trifecta), PIR-2026-0036 (malicious postmark-mcp package) - the tool-layer / untrusted-input agent-failure family. This record differs in surface: the defect is in a coding agent's OWN harness (config loader + built-in git tools) abused by a cloned repository, not in an MCP server; and it is a cluster of four coordinated CVEs treated as one incident because they share the same product, disclosure and root error
- `aiid_incident_id`: unknown (none located as of 2026-09-09)
- `confidence`: high on the identity, mechanism, CVE ids, CVSS scores, affected/fixed versions and disclosure of all four issues, from the four GitHub Security Advisories; no individual discoverer is credited (recorded as such, not as unknown-pending); no in-the-wild exploitation is claimed

### Verification notes
- 2026-09-09: all four GitHub Security Advisories read and cross-checked - GHSA-gx45-xrj5-g6c4 (CVE-2026-75911), GHSA-62f5-cp2p-vq95 (CVE-2026-75859), GHSA-c6mw-8xh8-gpq6 (CVE-2026-75912), GHSA-7j5w-7r7x-9v27 (CVE-2026-75913). Product = CodeWhale / codewhale-tui (formerly deepseek-tui), an AI coding-agent TUI; all four fixed in 0.8.64. Status flipped draft -> corroborated on that basis.
- Discovery note: the automated discovery lead paired the `git_show` advisory (GHSA-7j5w-7r7x-9v27) with CVE-2026-75913 but also showed a stray "CVE-2026-75913" against the `instructions` advisory; the primary sources resolve the `instructions` override to CVE-2026-75859, which is the id used here. Verify against the advisory pages, not the lead.
- Clustering: recorded as ONE incident rather than four PIRs because the four CVEs share the same product, the same coordinated disclosure, the same fixed release (0.8.64) and the same root error (repository-controlled input trusted past the approval gate). This mirrors how sibling-CVE families are handled elsewhere in the registry.
- Schema note (feed into v0): root_cause has no single clean token for "agent harness trusts untrusted repo-controlled config and tool arguments and fails to enforce its own approval/capability contract." This record uses tool-error, with the prompt-injection facet of CVE-2026-75859 (and the injection-triggered git-tool abuses) called out in prose; failure_locus=harness carries the real signal. If coding-agent harness/tool-contract failures recur, a dedicated token may be warranted.
