feat: enhance command classification and error handling; improve process checks and credential security

This commit is contained in:
asepharyana
2026-07-12 11:55:02 +07:00
parent 87d0aac596
commit ac99835eb4
10 changed files with 148 additions and 70 deletions
+11 -2
View File
@@ -34,17 +34,26 @@ impl Tool for GitCred {
/// Run `git credential <operation>`, forwarding stdin-less invocation to the git binary.
///
/// Flow: extract `operation` arg → spawn `git credential <operation>` → capture output.
/// Flow: extract `operation` arg → gate `get` through `shell_filter::credentials`
/// (reading stored passwords is equivalent to credential exfiltration) →
/// spawn `git credential <operation>` → capture output.
///
/// Why: `store`/`get`/`erase` are the only credential-helper subcommands git supports;
/// no stdin is piped, so this mainly surfaces helper output/errors rather than
/// performing an interactive credential exchange.
/// performing an interactive credential exchange. The `get` operation is gated
/// through the same filter that blocks `cat ~/.ssh/id_rsa`.
///
/// Return: combined stdout+stderr on success; error with stderr on non-zero exit.
fn run(&self, _ctx: &ToolCtx, args: &Value) -> Result<String> {
let operation = args.get("operation")
.and_then(|v| v.as_str())
.ok_or_else(|| anyhow!("missing required argument: operation"))?;
// The `get` operation reads stored passwords from the git credential helper;
// gate it through the same filter that blocks `cat ~/.ssh/id_rsa`.
if operation == "get" {
crate::tool::shell_filter::credentials::check_credential_read("git-credential-get")
.map_err(|e| anyhow!("blocked: {}", e))?;
}
let output = Command::new("git")
.arg("credential")
.arg(operation)