From c1840122f50f3fc7fc1ff3e2c6cfd70d195015eb Mon Sep 17 00:00:00 2001 From: Eva Wong Date: Wed, 18 Mar 2026 10:28:31 -0700 Subject: [PATCH] Fail closed for legacy MDM security config --- codex-rs/core/src/config_loader/macos.rs | 19 +++++++++++ codex-rs/core/src/config_loader/tests.rs | 42 ++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/codex-rs/core/src/config_loader/macos.rs b/codex-rs/core/src/config_loader/macos.rs index 5570e97c54..85773201c2 100644 --- a/codex-rs/core/src/config_loader/macos.rs +++ b/codex-rs/core/src/config_loader/macos.rs @@ -154,6 +154,16 @@ fn parse_managed_config_base64(encoded: &str) -> io::Result io::Result bool { + let path = dropped_entry + .split_once(':') + .map_or(dropped_entry, |(path, _)| path) + .trim(); + let top_level = path.split(['.', '[']).next().unwrap_or(path); + matches!(top_level, "approval_policy" | "sandbox_mode") +} + fn parse_managed_requirements_base64(encoded: &str) -> io::Result { let source = managed_preferences_requirements_source(); let raw_toml = decode_managed_preferences_base64(encoded).map_err(|err| { diff --git a/codex-rs/core/src/config_loader/tests.rs b/codex-rs/core/src/config_loader/tests.rs index c05e4543cd..6dc15ac02b 100644 --- a/codex-rs/core/src/config_loader/tests.rs +++ b/codex-rs/core/src/config_loader/tests.rs @@ -468,6 +468,48 @@ writable_roots = ["relative/path"] Ok(()) } +#[cfg(target_os = "macos")] +#[tokio::test] +async fn managed_preferences_invalid_security_config_entry_fails_closed() -> anyhow::Result<()> { + use base64::Engine; + + for (payload, expected_fragment) in [ + ( + "approval_policy = \"bogus\"\nmodel = \"managed\"\n", + "approval_policy", + ), + ( + "sandbox_mode = \"bogus\"\nmodel = \"managed\"\n", + "sandbox_mode", + ), + ] { + let tmp = tempdir()?; + let err = load_config_layers_state( + tmp.path(), + Some(AbsolutePathBuf::try_from(tmp.path())?), + &[] as &[(String, TomlValue)], + LoaderOverrides { + managed_config_path: Some(tmp.path().join("managed_config.toml")), + managed_preferences_base64: Some( + base64::prelude::BASE64_STANDARD.encode(payload.as_bytes()), + ), + macos_managed_config_requirements_base64: None, + }, + CloudRequirementsLoader::default(), + ) + .await + .expect_err("invalid managed security config should fail closed"); + + assert_eq!(err.kind(), std::io::ErrorKind::InvalidData); + let message = err.to_string(); + assert!(message.contains("Error parsing managed config from MDM")); + assert!(message.contains(expected_fragment), "{message}"); + assert!(message.contains("bogus"), "{message}"); + } + + Ok(()) +} + #[cfg(target_os = "macos")] #[tokio::test] async fn managed_preferences_ignore_invalid_payload() -> anyhow::Result<()> {