Sep 5, 2026·5 min read·31 visits
An input validation failure in CodeWhale allows attackers to inject Git command-line options via tool revision parameters, enabling arbitrary file disclosure from the hosting environment.
An argument injection vulnerability in CodeWhale (CVE-2026-75912 / GHSA-c6mw-8xh8-gpq6) allows unauthenticated remote attackers to execute arbitrary option commands on the git binary. By passing malicious command-line flags inside git_blame and git_show tool helper functions, an attacker can bypass typical access controls to read arbitrary local system files via the underlying git process.
CodeWhale is an AI-assisted terminal user interface (TUI) and coding companion that incorporates automated tools to interact with Git repositories. Among these integration capabilities are the git_blame and git_show helper utilities, which parse local codebases and structural changes to enrich LLM contexts.
The attack surface exists where CodeWhale tools process user-supplied parameters to construct and execute operating system commands. Specifically, the software fails to sanitize or constrain the revision (rev) parameter, which determines which branch, commit hash, or tag is queried by the local git client.
Because this component exposes programmatic controls directly to inputs generated by potentially untrusted sources (such as third-party code modifications or direct agent instructions), improper input sanitization leads to command-line flag injection. This vulnerability is formally classified as CWE-88 (Improper Neutralization of Argument Delimiters in a Command).
The root cause of this vulnerability lies in the dynamic assembly of external process arguments without validation. In Rust, standard application development leverages the std::process::Command struct to spawn system processes.
While std::process::Command does not execute commands within an intermediate system shell like /bin/sh or cmd.exe by default, it does not prevent argument or option injection. If a user-supplied string begins with a hyphen character (-), the underlying operating system executes the target binary, and that binary processes the argument as an administrative switch or configuration option rather than as a positional file or revision name.
In CodeWhale's implementation, the unvalidated rev parameter is passed directly into the process argument array for git blame. The git-blame binary supports the --contents <file> option, which instructs the command to perform its history analysis using a specified disk file's actual contents rather than the database state. Consequently, an attacker can input an option-shaped string such as --contents=/etc/passwd to force the git client to read local files outside the target repository context.
The vulnerability was mitigated in commit 9a34b5034d29f05d1f28fa61b04719ca6a741020 by implementing validation routines that block leading hyphens, control characters, and empty parameters.
Prior to the patch, both GitShowTool and GitBlameTool retrieved the revision parameter from the tool request input block and directly passed it to the git executable wrapper. Below is the comparative code change implemented in crates/tui/src/tools/git_history.rs to address this exposure:
// Vulnerable vs. Patched execution context in crates/tui/src/tools/git_history.rs
@@ -204,6 +204,7 @@ impl ToolSpec for GitShowTool {
async fn execute(&self, input: Value, context: &ToolContext) -> Result<ToolResult, ToolError> {
let rev = required_str(&input, "rev")?;
+ validate_git_rev(rev)?; // Added input validation before executing system process
let git_ctx = resolve_git_context(context, optional_str(&input, "path"))?;
let patch = optional_bool(&input, "patch", true);
...
@@ -339,6 +340,7 @@ impl ToolSpec for GitBlameTool {
let rev = optional_str(&input, "rev").unwrap_or("HEAD");
+ validate_git_rev(rev)?; // Added option validation block to prevent parameter abuse
let start_line = optional_u64(&input, "start_line", DEFAULT_BLAME_START_LINE).max(1);To ensure complete isolation, the maintainers defined a rigorous verification helper named validate_git_rev that screens incoming revision strings:
fn validate_git_rev(rev: &str) -> Result<(), ToolError> {
let trimmed = rev.trim();
if trimmed.is_empty() {
return Err(ToolError::invalid_input(
"git revision must not be empty".to_string(),
));
}
// Ensure the parameter is not processed as a command-line flag
if trimmed.starts_with('-') {
return Err(ToolError::invalid_input(
"git revision must not start with '-'".to_string(),
));
}
// Prevent execution flow truncation and parser manipulation
if trimmed.chars().any(|ch| ch == '\0' || ch.is_ascii_control()) {
return Err(ToolError::invalid_input(
"git revision must not contain control characters".to_string(),
));
}
Ok(())
}This validator enforces critical constraints. The call to .trim() prevents attackers from using spaces to bypass the starts_with('-') check, while the control character filter stops binary path modifications using null bytes.
Exploitation of CVE-2026-75912 requires providing a manipulated tool payload to the CodeWhale execution layer. This can occur directly if the tool allows direct interface interactions, or indirectly if an attacker manages to trigger prompt-injection payloads via malicious repositories or files reviewed by the AI companion.
An attacker supplies a structured JSON command payload containing the target option injection within the rev argument:
{
"path": "Cargo.toml",
"rev": "--contents=/etc/passwd"
}Upon execution, CodeWhale runs the system command without verification, generating the following process execution vector:
git blame --contents=/etc/passwd Cargo.tomlBecause the git-blame process is instructed to read from /etc/passwd, it parses the sensitive configuration file line-by-line and decorates each record with synthetic commit headers. The resultant output stream is then returned to the AI context as the command execution output:
00000000 (Not Committed Yet 2026-06-21 22:13:26 +0000 1) root:x:0:0:root:/root:/bin/bash
00000000 (Not Committed Yet 2026-06-21 22:13:26 +0000 2) daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinThis output exposes system configuration values and local credentials directly, leading to immediate information exposure.
The security implications of CVE-2026-75912 are significant. Successful exploitation grants attackers read-access to any arbitrary file on the host filesystem that the executing process user has permissions to access.
In cloud development environments, workspace instances, or shared build pipelines, this read-access exposes sensitive parameters including environment variables, private developer keys (e.g., SSH keys, AWS access secrets), configuration files, and proprietary source code files. While the vulnerability does not directly permit write-access or code execution, the disclosed credentials can be used to pivot and achieve broader network compromise.
The CVSS v4.0 rating is 8.3 (High) due to the low complexity of the attack vector coupled with high subsequent confidentiality impacts. The scope change metric is marked as High because the vulnerability leaks data across isolated file systems and outputs it back to the processing application layer.
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
CodeWhale Hmbown | >= 0.3.27, < 0.8.41 | 0.8.41 |
CodeWhale Hmbown | >= 0.8.41, < 0.8.64 | 0.8.64 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-88: Improper Neutralization of Argument Delimiters in a Command ('Argument Injection') |
| Attack Vector | Network / Remote |
| CVSS v4.0 Base Score | 8.3 |
| EPSS Score | 0.00322 |
| Impact | High (Arbitrary File Disclosure) |
| Exploit Status | poc |
| KEV Status | Not Listed |
Improper Neutralization of Argument Delimiters in a Command ('Argument Injection')
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.