mirror of
https://github.com/openai/codex.git
synced 2026-09-05 15:18:41 +00:00
Revert "Use stable Windows sandbox test harness"
This reverts commit 5b19b08571.
This commit is contained in:
@@ -15,14 +15,27 @@ use codex_protocol::permissions::FileSystemSandboxEntry;
|
||||
use codex_protocol::permissions::FileSystemSandboxPolicy;
|
||||
use codex_protocol::permissions::FileSystemSpecialPath;
|
||||
use codex_protocol::permissions::NetworkSandboxPolicy;
|
||||
use codex_protocol::protocol::EventMsg;
|
||||
use codex_protocol::protocol::Op;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
use core_test_support::PathExt;
|
||||
use core_test_support::load_default_config_for_test_with_cloud_config_bundle;
|
||||
use core_test_support::responses::ev_assistant_message;
|
||||
use core_test_support::responses::ev_completed;
|
||||
use core_test_support::responses::ev_function_call;
|
||||
use core_test_support::responses::ev_response_created;
|
||||
use core_test_support::responses::mount_sse_sequence;
|
||||
use core_test_support::responses::sse;
|
||||
use core_test_support::responses::start_mock_server;
|
||||
use core_test_support::test_codex::test_codex;
|
||||
use core_test_support::wait_for_event;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde_json::json;
|
||||
use serial_test::serial;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tempfile::TempDir;
|
||||
|
||||
struct EnvVarGuard {
|
||||
@@ -328,23 +341,22 @@ async fn windows_elevated_enforces_deny_read_and_protects_setup_marker() -> anyh
|
||||
#[serial(codex_home)]
|
||||
async fn windows_elevated_enforces_managed_deny_read_for_shell_subprocess() -> anyhow::Result<()> {
|
||||
stage_windows_sandbox_helpers()?;
|
||||
let sandbox_home =
|
||||
codex_home_for_windows_sandbox_test("windows-elevated-managed-deny-read-codex-home")?;
|
||||
let _codex_home_guard = EnvVarGuard::set("CODEX_HOME", sandbox_home.path().as_os_str());
|
||||
let config_home = TempDir::new()?;
|
||||
let codex_home = Arc::new(TempDir::new()?);
|
||||
let _codex_home_guard = EnvVarGuard::set("CODEX_HOME", codex_home.path().as_os_str());
|
||||
std::fs::write(
|
||||
config_home.path().join(CONFIG_TOML_FILE),
|
||||
codex_home.path().join(CONFIG_TOML_FILE),
|
||||
r#"[windows]
|
||||
sandbox = "elevated"
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let workspace = TempDir::new()?;
|
||||
let cwd = dunce::canonicalize(workspace.path())?.abs();
|
||||
let denied_path = cwd.join("secret.env");
|
||||
let allowed_path = cwd.join("public.txt");
|
||||
let protected_dir = TempDir::new()?;
|
||||
let denied_path = protected_dir.path().join("secret.env");
|
||||
let allowed_path = protected_dir.path().join("public.txt");
|
||||
std::fs::write(&denied_path, "managed secret\n")?;
|
||||
std::fs::write(&allowed_path, "public ok\n")?;
|
||||
let denied_path = dunce::canonicalize(denied_path)?.abs();
|
||||
let allowed_path = dunce::canonicalize(allowed_path)?.abs();
|
||||
let denied_path_toml = toml::Value::String(denied_path.to_string_lossy().into()).to_string();
|
||||
let requirements = format!(
|
||||
r#"[permissions.filesystem]
|
||||
@@ -355,18 +367,26 @@ allowed_sandbox_implementations = ["elevated"]
|
||||
"#
|
||||
);
|
||||
|
||||
let config = load_default_config_for_test_with_cloud_config_bundle(
|
||||
&config_home,
|
||||
CloudConfigBundleFixture::loader_with_enterprise_requirement(requirements),
|
||||
)
|
||||
.await;
|
||||
let server = start_mock_server().await;
|
||||
let mut builder = test_codex()
|
||||
.with_home(Arc::clone(&codex_home))
|
||||
.with_cloud_config_bundle(
|
||||
CloudConfigBundleFixture::loader_with_enterprise_requirement(requirements),
|
||||
)
|
||||
.with_windows_cmd_shell()
|
||||
.with_config(|config| {
|
||||
config.permissions.windows_sandbox_private_desktop = false;
|
||||
});
|
||||
let fixture = builder.build(&server).await?;
|
||||
|
||||
assert_eq!(
|
||||
config.permissions.windows_sandbox_mode,
|
||||
fixture.config.permissions.windows_sandbox_mode,
|
||||
Some(codex_config::types::WindowsSandboxModeToml::Elevated)
|
||||
);
|
||||
let permission_profile = config.permissions.effective_permission_profile();
|
||||
assert!(
|
||||
permission_profile
|
||||
fixture
|
||||
.session_configured
|
||||
.permission_profile
|
||||
.file_system_sandbox_policy()
|
||||
.entries
|
||||
.iter()
|
||||
@@ -377,58 +397,73 @@ allowed_sandbox_implementations = ["elevated"]
|
||||
FileSystemPath::Path { path } if path == &denied_path
|
||||
)
|
||||
}),
|
||||
"managed deny-read path should reach the runtime permission profile"
|
||||
"managed deny-read path should reach the configured session"
|
||||
);
|
||||
|
||||
let ExecToolCallOutput {
|
||||
exit_code,
|
||||
stdout,
|
||||
..
|
||||
} = process_exec_tool_call(
|
||||
ExecParams {
|
||||
command: vec![
|
||||
"cmd.exe".to_string(),
|
||||
"/D".to_string(),
|
||||
"/C".to_string(),
|
||||
"(type secret.env 1>NUL 2>NUL && echo SECRET-READ || echo SECRET-DENIED) & type public.txt"
|
||||
.to_string(),
|
||||
],
|
||||
cwd: cwd.clone(),
|
||||
expiration: 10_000.into(),
|
||||
capture_policy: ExecCapturePolicy::ShellTool,
|
||||
env: HashMap::new(),
|
||||
network: None,
|
||||
sandbox_permissions: SandboxPermissions::UseDefault,
|
||||
windows_sandbox_level: WindowsSandboxLevel::Elevated,
|
||||
windows_sandbox_private_desktop: false,
|
||||
justification: None,
|
||||
arg0: None,
|
||||
},
|
||||
&permission_profile,
|
||||
&cwd,
|
||||
std::slice::from_ref(&cwd),
|
||||
&None,
|
||||
/*use_legacy_landlock*/ false,
|
||||
/*stdout_stream*/ None,
|
||||
let call_id = "managed-deny-read";
|
||||
let command = format!(
|
||||
"(type \"{}\" 1>NUL 2>NUL && echo SECRET-READ || echo SECRET-DENIED) & type \"{}\"",
|
||||
denied_path.display(),
|
||||
allowed_path.display()
|
||||
);
|
||||
let args = json!({
|
||||
"command": command,
|
||||
"login": false,
|
||||
"timeout_ms": 10_000,
|
||||
});
|
||||
let request_log = mount_sse_sequence(
|
||||
&server,
|
||||
vec![
|
||||
sse(vec![
|
||||
ev_response_created("resp-1"),
|
||||
ev_function_call(call_id, "shell_command", &serde_json::to_string(&args)?),
|
||||
ev_completed("resp-1"),
|
||||
]),
|
||||
sse(vec![
|
||||
ev_assistant_message("msg-1", "done"),
|
||||
ev_completed("resp-2"),
|
||||
]),
|
||||
],
|
||||
)
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
assert_eq!(exit_code, 0, "sandboxed command should complete");
|
||||
fixture
|
||||
.codex
|
||||
.submit(Op::UserInput {
|
||||
items: vec![UserInput::Text {
|
||||
text: "read the fixture files".into(),
|
||||
text_elements: Vec::new(),
|
||||
}],
|
||||
environments: None,
|
||||
final_output_json_schema: None,
|
||||
responsesapi_client_metadata: None,
|
||||
additional_context: Default::default(),
|
||||
thread_settings: Default::default(),
|
||||
})
|
||||
.await?;
|
||||
wait_for_event(&fixture.codex, |event| {
|
||||
matches!(event, EventMsg::TurnComplete(_))
|
||||
})
|
||||
.await;
|
||||
|
||||
let output = request_log
|
||||
.function_call_output_text(call_id)
|
||||
.context("shell output present")?;
|
||||
assert!(
|
||||
stdout.text.contains("SECRET-DENIED"),
|
||||
"managed deny-read should block the subprocess read: {stdout:?}"
|
||||
output.contains("SECRET-DENIED"),
|
||||
"managed deny-read should block the subprocess read: {output}"
|
||||
);
|
||||
assert!(
|
||||
!stdout.text.contains("SECRET-READ"),
|
||||
"managed deny-read must not allow the subprocess read: {stdout:?}"
|
||||
!output.contains("SECRET-READ"),
|
||||
"managed deny-read must not allow the subprocess read: {output}"
|
||||
);
|
||||
assert!(
|
||||
stdout.text.contains("public ok"),
|
||||
"allowed reads should still work: {stdout:?}"
|
||||
output.contains("public ok"),
|
||||
"allowed reads should still work: {output}"
|
||||
);
|
||||
assert!(
|
||||
!stdout.text.contains("managed secret"),
|
||||
"denied file contents leaked into shell output: {stdout:?}"
|
||||
!output.contains("managed secret"),
|
||||
"denied file contents leaked into shell output: {output}"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user