Sep 5, 2026·5 min read·1 visit
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')
A critical Server-Side Request Forgery (SSRF) bypass vulnerability exists in CodeWhale before version 0.8.64 (and version 0.8.41 in the 0.8.x branch) due to a Time-of-Check to Time-of-Use (TOCTOU) bug in its DNS pre-flight validation mechanism. By returning a temporary resolution failure during validation and subsequently resolving to restricted IPs during HTTP execution, attackers can bypass security rules.
SurrealDB prior to version 3.2.0 is vulnerable to an authorization bypass where authenticated users can invoke custom API endpoints belonging to other tenants. This cross-tenant data access occurs because the system fails to validate authorization scope boundaries against request-supplied namespace and database identifiers before executing scripts with elevated definer's rights.
An incorrect authorization vulnerability (CWE-863) in SurrealDB allows authenticated, low-privileged users to execute unauthorized state-modifying queries. This occurs because the database disabled permissions during evaluation of custom PERMISSIONS WHERE predicates to prevent infinite recursion.
SiYuan before v3.7.4 fails to enforce publish-access filters on five filetree path-resolution endpoints, allowing unauthenticated attackers to reconstruct private directory layouts and map document structures.
Prior to version v3.7.4, the SiYuan personal knowledge management system contained a critical logical authorization vulnerability within its database view rendering component. The flaws allowed unauthenticated remote attackers to bypass publish-access filters on databases, exposing sensitive Relation and Rollup cell contents belonging to private or password-protected repositories.
An information disclosure vulnerability exists in SiYuan prior to v3.7.4 due to missing authorization checks on the getEncryptedNotebookStatus API endpoint, allowing unprivileged or anonymous users to enumerate protected notebooks.