Sep 5, 2026·5 min read·28 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')
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.
Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.
Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.
An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.
In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.
A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.