mirror of
https://github.com/openai/codex.git
synced 2026-10-21 17:48:44 +00:00
Prevent launch context from reaching child processes (#37607)
## Why Model-reachable child processes should not inherit Codex launch context. ## What changed - Treat `OPENAI_FEDERATION_RULE_ID` and `OPENAI_IDENTITY_TOKEN_FILE` as non-inheritable environment variables, with case-insensitive matching. - Remove them after shell environment policy overrides and before spawning commands across execution, MCP, hooks, Git helpers, and remote helper processes. ## Testing - Cover inherited and explicitly configured variants, including mixed-case names. - Verify the variables are absent from real child environments and app-server command and process execution. GitOrigin-RevId: 2535527893985fef0995617f4c5b2462bea7c136
This commit is contained in:
@@ -4,6 +4,44 @@ use crate::config_types::ShellEnvironmentPolicyInherit;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub const CODEX_THREAD_ID_ENV_VAR: &str = "CODEX_THREAD_ID";
|
||||
pub const OPENAI_FEDERATION_RULE_ID_ENV_VAR: &str = "OPENAI_FEDERATION_RULE_ID";
|
||||
pub const OPENAI_IDENTITY_TOKEN_FILE_ENV_VAR: &str = "OPENAI_IDENTITY_TOKEN_FILE";
|
||||
|
||||
/// Environment variables that model-reachable child processes must not inherit.
|
||||
pub const NON_INHERITABLE_ENV_VARS: &[&str] = &[
|
||||
OPENAI_FEDERATION_RULE_ID_ENV_VAR,
|
||||
OPENAI_IDENTITY_TOKEN_FILE_ENV_VAR,
|
||||
];
|
||||
|
||||
pub fn is_non_inheritable_env_var(name: &str) -> bool {
|
||||
NON_INHERITABLE_ENV_VARS
|
||||
.iter()
|
||||
.any(|restricted| restricted.eq_ignore_ascii_case(name))
|
||||
}
|
||||
|
||||
/// Configures a child command to omit non-inheritable variables from the
|
||||
/// process environment and explicit command overrides.
|
||||
///
|
||||
/// This prevents accidental propagation of Codex launch context; it is not a
|
||||
/// filesystem security boundary for the referenced identity-token file.
|
||||
pub fn scrub_non_inheritable_env_vars(command: &mut std::process::Command) {
|
||||
let configured_names = command
|
||||
.get_envs()
|
||||
.map(|(name, _)| name.to_os_string())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
for name in NON_INHERITABLE_ENV_VARS {
|
||||
command.env_remove(name);
|
||||
}
|
||||
for name in std::env::vars_os()
|
||||
.map(|(name, _)| name)
|
||||
.chain(configured_names)
|
||||
{
|
||||
if name.to_str().is_some_and(is_non_inheritable_env_var) {
|
||||
command.env_remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a shell environment from the supplied process environment and
|
||||
/// shell-environment policy.
|
||||
@@ -106,6 +144,10 @@ where
|
||||
env_map.insert(CODEX_THREAD_ID_ENV_VAR.to_string(), thread_id.to_string());
|
||||
}
|
||||
|
||||
// Restricted launch context cannot be restored through user-provided shell
|
||||
// environment overrides.
|
||||
env_map.retain(|name, _| !is_non_inheritable_env_var(name));
|
||||
|
||||
env_map
|
||||
}
|
||||
|
||||
@@ -148,6 +190,10 @@ pub const WINDOWS_CORE_ENV_VARS: &[&str] = &[
|
||||
"PWSH",
|
||||
];
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "shell_environment_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
#[cfg(all(test, target_os = "windows"))]
|
||||
mod windows_tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user