mirror of
https://github.com/openai/codex.git
synced 2026-11-14 21:40:39 +00:00
Fix Windows execpolicy matching for PowerShell wrappers
This commit is contained in:
@@ -37,6 +37,7 @@ use crate::sandboxing::SandboxPermissions;
|
||||
use crate::tools::sandboxing::ExecApprovalRequirement;
|
||||
use codex_shell_command::bash::parse_shell_lc_plain_commands;
|
||||
use codex_shell_command::bash::parse_shell_lc_single_command_prefix;
|
||||
use codex_shell_command::split_powershell_command_sequence;
|
||||
use codex_utils_absolute_path::AbsolutePathBuf;
|
||||
use shlex::try_join as shlex_try_join;
|
||||
|
||||
@@ -705,6 +706,12 @@ fn commands_for_exec_policy(command: &[String]) -> (Vec<Vec<String>>, bool) {
|
||||
return (commands, false);
|
||||
}
|
||||
|
||||
if let Some(commands) = split_powershell_command_sequence(command)
|
||||
&& !commands.is_empty()
|
||||
{
|
||||
return (commands, false);
|
||||
}
|
||||
|
||||
if let Some(single_command) = parse_shell_lc_single_command_prefix(command) {
|
||||
return (vec![single_command], true);
|
||||
}
|
||||
|
||||
@@ -674,6 +674,23 @@ fn commands_for_exec_policy_falls_back_for_whitespace_shell_script() {
|
||||
assert_eq!(commands_for_exec_policy(&command), (vec![command], false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn commands_for_exec_policy_splits_powershell_command() {
|
||||
let command = vec![
|
||||
"pwsh".to_string(),
|
||||
"-Command".to_string(),
|
||||
"git add -A".to_string(),
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
commands_for_exec_policy(&command),
|
||||
(
|
||||
vec![vec!["git".to_string(), "add".to_string(), "-A".to_string(),]],
|
||||
false,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn ignore_user_config_keeps_user_policy_files() -> std::io::Result<()> {
|
||||
let temp = tempdir()?;
|
||||
@@ -1637,6 +1654,32 @@ prefix_rule(pattern=["bash"], decision="allow")
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn powershell_command_bypasses_sandbox_when_inner_command_matches_policy_allow() {
|
||||
let policy_src = r#"prefix_rule(pattern=["git", "add"], decision="allow")"#;
|
||||
|
||||
assert_exec_approval_requirement_for_command(
|
||||
ExecApprovalRequirementScenario {
|
||||
policy_src: Some(policy_src.to_string()),
|
||||
command: vec![
|
||||
"pwsh".to_string(),
|
||||
"-Command".to_string(),
|
||||
"git add -A".to_string(),
|
||||
],
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
sandbox_policy: SandboxPolicy::new_workspace_write_policy(),
|
||||
file_system_sandbox_policy: workspace_write_file_system_sandbox_policy(),
|
||||
sandbox_permissions: SandboxPermissions::RequireEscalated,
|
||||
prefix_rule: None,
|
||||
},
|
||||
ExecApprovalRequirement::Skip {
|
||||
bypass_sandbox: true,
|
||||
proposed_execpolicy_amendment: None,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
fn derive_requested_execpolicy_amendment_for_test(
|
||||
prefix_rule: Option<&Vec<String>>,
|
||||
matched_rules: &[RuleMatch],
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::path::Path;
|
||||
/// On Windows, we conservatively allow only clearly read-only PowerShell invocations
|
||||
/// that match a small safelist. Anything else (including direct CMD commands) is unsafe.
|
||||
pub fn is_safe_command_windows(command: &[String]) -> bool {
|
||||
if let Some(commands) = try_parse_powershell_command_sequence(command) {
|
||||
if let Some(commands) = split_powershell_command_sequence(command) {
|
||||
commands
|
||||
.iter()
|
||||
.all(|cmd| is_safe_powershell_command(cmd.as_slice()))
|
||||
@@ -18,7 +18,7 @@ pub fn is_safe_command_windows(command: &[String]) -> bool {
|
||||
|
||||
/// Returns each command sequence if the invocation starts with a PowerShell binary.
|
||||
/// For example, the tokens from `pwsh Get-ChildItem | Measure-Object` become two sequences.
|
||||
fn try_parse_powershell_command_sequence(command: &[String]) -> Option<Vec<Vec<String>>> {
|
||||
pub fn split_powershell_command_sequence(command: &[String]) -> Option<Vec<Vec<String>>> {
|
||||
let (exe, rest) = command.split_first()?;
|
||||
if is_powershell_executable(exe) {
|
||||
parse_powershell_invocation(exe, rest)
|
||||
|
||||
@@ -9,3 +9,4 @@ pub mod powershell;
|
||||
|
||||
pub use command_safety::is_dangerous_command;
|
||||
pub use command_safety::is_safe_command;
|
||||
pub use command_safety::windows_safe_commands::split_powershell_command_sequence;
|
||||
|
||||
Reference in New Issue
Block a user