Stop treating Git commands as inherently safe (#39524)

## Why

Repository configuration can cause even read-only Git commands to execute
helpers, so Git command arguments alone are not enough to establish trust.

## What changed

- Remove Git commands from the known-safe command classification on Unix and
  Windows, including commands nested in supported shells.
- Under the `unless-trusted` approval policy, require approval for commands such
  as `git status` unless an explicit execution policy rule allows them.

## Testing

- Cover direct, shell-wrapped, absolute-path, and PowerShell Git commands.
- Verify `git status` approval behavior with and without an explicit allow rule.

GitOrigin-RevId: dd04e0ddca0c56ba64ae64abe6e658bae7bf5a4d
This commit is contained in:
iceweasel-oai authored and copyberry committed 2026-08-19 18:01:14 +00:00
1 parent 1b450c7912
commit 3b45c29062
5 files changed
+170 -436

No files matched your search

+48 -2
View File
@@ -992,6 +992,52 @@ async fn exec_approval_requirement_prefers_execpolicy_match() {
.await;
}
#[tokio::test]
async fn git_status_obeys_approval_policy_and_explicit_rules() {
let command = vec_str(&["git", "status"]);
let amendment = Some(ExecPolicyAmendment::new(command.clone()));
for (approval_policy, policy_src, expected_requirement) in [
(
AskForApproval::UnlessTrusted,
None,
ExecApprovalRequirement::NeedsApproval {
reason: None,
proposed_execpolicy_amendment: amendment.clone(),
},
),
(
AskForApproval::OnRequest,
None,
ExecApprovalRequirement::Skip {
bypass_sandbox: false,
proposed_execpolicy_amendment: amendment,
},
),
(
AskForApproval::UnlessTrusted,
Some(r#"prefix_rule(pattern=["git", "status"], decision="allow")"#.to_string()),
ExecApprovalRequirement::Skip {
bypass_sandbox: true,
proposed_execpolicy_amendment: None,
},
),
] {
assert_exec_approval_requirement_for_command(
ExecApprovalRequirementScenario {
policy_src,
command: command.clone(),
approval_policy,
permission_profile: PermissionProfile::workspace_write(),
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
},
expected_requirement,
)
.await;
}
}
#[tokio::test]
async fn absolute_path_exec_approval_requirement_matches_host_executable_rules() {
let git_path = host_program_path("git");
@@ -1044,8 +1090,8 @@ prefix_rule(pattern=["git"], decision="prompt")
sandbox_permissions: SandboxPermissions::UseDefault,
prefix_rule: None,
},
ExecApprovalRequirement::Skip {
bypass_sandbox: false,
ExecApprovalRequirement::NeedsApproval {
reason: None,
proposed_execpolicy_amendment: Some(ExecPolicyAmendment::new(vec![
disallowed_git_path,
"status".to_string(),