mirror of
https://github.com/openai/codex.git
synced 2026-11-08 20:40:33 +00:00
Omit sensitive process inputs from spawn trace logs (#60034)
## Why Command arguments and environment variables can contain credentials. Logging them when spawning a child process can expose those credentials in trace output. ## What changed Replace argument, `arg0`, and environment contents in `spawn_child_async` trace logs with argument and environment counts and a flag indicating whether `arg0` is overridden. Keep the program, working directory, network sandbox policy, and stdio policy in the trace. ## Testing Add a regression test that captures trace output and verifies that argument, `arg0`, and environment canaries are omitted while the program path remains visible. GitOrigin-RevId: c317e7dcc6fd8b4eafb6fcfe98dc8634807c813d
This commit is contained in:
@@ -63,8 +63,16 @@ pub(crate) async fn spawn_child_async(request: SpawnChildRequest<'_>) -> std::io
|
||||
|
||||
env.retain(|name, _| !is_non_inheritable_env_var(name));
|
||||
|
||||
// Both command arguments and environment variables can contain credentials.
|
||||
trace!(
|
||||
"spawn_child_async: {program:?} {args:?} {arg0:?} {cwd:?} {network_sandbox_policy:?} {stdio_policy:?} {env:?}"
|
||||
?program,
|
||||
?cwd,
|
||||
?network_sandbox_policy,
|
||||
?stdio_policy,
|
||||
arg_count = args.len(),
|
||||
has_arg0_override = arg0.is_some(),
|
||||
env_count = env.len(),
|
||||
"spawn_child_async"
|
||||
);
|
||||
|
||||
let mut cmd = match stdio_policy {
|
||||
@@ -135,3 +143,7 @@ pub(crate) async fn spawn_child_async(request: SpawnChildRequest<'_>) -> std::io
|
||||
|
||||
cmd.kill_on_drop(true).spawn()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "spawn_tests.rs"]
|
||||
mod tests;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#![cfg(test)]
|
||||
|
||||
use super::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[tokio::test]
|
||||
async fn spawn_trace_omits_sensitive_inputs() -> std::io::Result<()> {
|
||||
let dir = tempfile::tempdir()?;
|
||||
let capture = tempfile::NamedTempFile::new()?;
|
||||
let subscriber = tracing_subscriber::fmt()
|
||||
.with_max_level(tracing::Level::TRACE)
|
||||
.with_writer(Arc::new(capture.reopen()?))
|
||||
.finish();
|
||||
let _guard = tracing::subscriber::set_default(subscriber);
|
||||
|
||||
let result = spawn_child_async(SpawnChildRequest {
|
||||
program: dir.path().join("missing-test-program"),
|
||||
args: vec!["canary-argument".into()],
|
||||
arg0: Some("canary-arg0"),
|
||||
cwd: AbsolutePathBuf::from_absolute_path(dir.path())?,
|
||||
network_sandbox_policy: NetworkSandboxPolicy::Enabled,
|
||||
network: None,
|
||||
stdio_policy: StdioPolicy::RedirectForShellTool,
|
||||
env: HashMap::from([("SETTING".into(), "canary-env-value".into())]),
|
||||
})
|
||||
.await;
|
||||
assert!(result.is_err());
|
||||
|
||||
let logs = std::fs::read_to_string(capture.path())?;
|
||||
assert!(logs.contains("missing-test-program"));
|
||||
assert!(!logs.contains("canary-"));
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user