mirror of
https://github.com/openai/codex.git
synced 2026-04-24 06:35:50 +00:00
Handle PowerShell prefix rules in execpolicy
This commit is contained in:
@@ -25,6 +25,7 @@ use codex_protocol::permissions::FileSystemSandboxKind;
|
||||
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
||||
use codex_protocol::protocol::AskForApproval;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use codex_shell_command::command_safety::windows_safe_commands::try_parse_powershell_command_sequence;
|
||||
use thiserror::Error;
|
||||
use tokio::fs;
|
||||
use tokio::task::spawn_blocking;
|
||||
@@ -627,6 +628,12 @@ fn commands_for_exec_policy(command: &[String]) -> (Vec<Vec<String>>, bool) {
|
||||
return (commands, false);
|
||||
}
|
||||
|
||||
if let Some(commands) = try_parse_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);
|
||||
}
|
||||
|
||||
@@ -556,6 +556,48 @@ fn commands_for_exec_policy_falls_back_for_whitespace_shell_script() {
|
||||
assert_eq!(commands_for_exec_policy(&command), (vec![command], false));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn powershell_single_command_prefix_rules_can_bypass_sandbox() {
|
||||
if which::which("pwsh")
|
||||
.or_else(|_| which::which("powershell"))
|
||||
.is_err()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let policy_src = r#"prefix_rule(pattern=["git", "add"], decision="allow")"#;
|
||||
let mut parser = PolicyParser::new();
|
||||
parser
|
||||
.parse("test.rules", policy_src)
|
||||
.expect("parse policy");
|
||||
|
||||
let command = vec![
|
||||
"pwsh".to_string(),
|
||||
"-NoProfile".to_string(),
|
||||
"-Command".to_string(),
|
||||
"git add -A".to_string(),
|
||||
];
|
||||
|
||||
let requirement = ExecPolicyManager::new(Arc::new(parser.build()))
|
||||
.create_exec_approval_requirement_for_command(ExecApprovalRequest {
|
||||
command: &command,
|
||||
approval_policy: AskForApproval::OnRequest,
|
||||
sandbox_policy: &SandboxPolicy::new_read_only_policy(),
|
||||
file_system_sandbox_policy: &read_only_file_system_sandbox_policy(),
|
||||
sandbox_permissions: SandboxPermissions::RequireEscalated,
|
||||
prefix_rule: None,
|
||||
})
|
||||
.await;
|
||||
|
||||
assert_eq!(
|
||||
requirement,
|
||||
ExecApprovalRequirement::Skip {
|
||||
bypass_sandbox: true,
|
||||
proposed_execpolicy_amendment: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn evaluates_heredoc_script_against_prefix_rules() {
|
||||
let policy_src = r#"prefix_rule(pattern=["python3"], decision="allow")"#;
|
||||
|
||||
@@ -22,7 +22,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 try_parse_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)
|
||||
|
||||
Reference in New Issue
Block a user