Filter environment variables in both sandbox modes
Whitelist mode now clears the parent env and re-adds a small allowlist (identity, terminal, locale, proxy, non-GUI XDG, vendor prefixes). Blacklist mode strips cloud credentials, backup passphrases, dangling socket pointers, and anything matching *_TOKEN, *_SECRET, *_PASSWORD, *_PASSPHRASE, *_API_KEY, *_PRIVATE_KEY, *_CLIENT_SECRET; vendor prefix carve-outs keep ANTHROPIC_API_KEY and friends. Users can override via --setenv KEY=VALUE and --unsetenv KEY (and the corresponding TOML keys), or opt out of the built-in policy entirely with --no-env-filter.
This commit is contained in:
@@ -3,6 +3,7 @@ use std::process::Command;
|
||||
|
||||
use crate::agents;
|
||||
use crate::blacklist;
|
||||
use crate::env;
|
||||
use crate::seccomp;
|
||||
use crate::{SandboxConfig, SandboxError, SandboxMode};
|
||||
|
||||
@@ -35,6 +36,9 @@ pub fn build_command(config: &SandboxConfig) -> Result<Command, SandboxError> {
|
||||
add_ro_bind(&mut cmd, path)?;
|
||||
}
|
||||
|
||||
add_env_policy(&mut cmd, config);
|
||||
add_user_env_overrides(&mut cmd, config);
|
||||
|
||||
cmd.args(["--remount-ro", "/"]);
|
||||
cmd.arg("--new-session");
|
||||
cmd.arg("--die-with-parent");
|
||||
@@ -55,6 +59,27 @@ pub fn build_command(config: &SandboxConfig) -> Result<Command, SandboxError> {
|
||||
Ok(cmd)
|
||||
}
|
||||
|
||||
fn add_env_policy(cmd: &mut Command, config: &SandboxConfig) {
|
||||
if !config.env_filter {
|
||||
return;
|
||||
}
|
||||
let parent_env: Vec<(String, String)> = std::env::vars().collect();
|
||||
let args = match config.mode {
|
||||
SandboxMode::Blacklist => env::blacklist_env_args(&parent_env),
|
||||
SandboxMode::Whitelist => env::whitelist_env_args(&parent_env),
|
||||
};
|
||||
cmd.args(args);
|
||||
}
|
||||
|
||||
fn add_user_env_overrides(cmd: &mut Command, config: &SandboxConfig) {
|
||||
for (key, value) in &config.setenv {
|
||||
cmd.arg("--setenv").arg(key).arg(value);
|
||||
}
|
||||
for key in &config.unsetenv {
|
||||
cmd.arg("--unsetenv").arg(key);
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_masks(cmd: &mut Command, masks: &[PathBuf]) {
|
||||
for path in masks {
|
||||
if path.is_file() {
|
||||
|
||||
Reference in New Issue
Block a user