Goal
After the per-tool harden PRs land, the per-tool helpers will have a lot of structural overlap. Generalize into one primitive + one registry, so future tools we wrap inherit defense-in-depth by default.
Architectural shape (from research agent)
pub struct ToolPolicy {
pub name: &'static str,
pub env_strip: &'static [&'static str],
pub arg_deny_exact: &'static [&'static str],
pub arg_deny_prefix: &'static [&'static str],
pub arg_deny_short_letters_in_bundle: &'static [char],
}
pub fn secure_command(policy: &ToolPolicy) -> Command {
let mut cmd = resolved_command(policy.name);
for v in UNIVERSAL_ENV_STRIP { cmd.env_remove(v); }
for v in policy.env_strip { cmd.env_remove(v); }
cmd
}
pub fn check_args(policy: &ToolPolicy, args: &[impl AsRef<str>]) -> Result<(), String> { ... }
Universal env-strip (applied to ALL wrapped tools regardless)
- Pager / editor:
EDITOR, VISUAL, PAGER, LESS, LESSOPEN, LESSCLOSE, MANPAGER
- Loader hijacks:
LD_PRELOAD, LD_AUDIT, LD_LIBRARY_PATH, DYLD_INSERT_LIBRARIES, DYLD_LIBRARY_PATH, DYLD_FRAMEWORK_PATH, DYLD_FALLBACK_*
- Lang-loader injections:
PERL5OPT, PERL5LIB, LUA_INIT, LUA_PATH, LUA_CPATH
- Shell metaprogramming:
BASH_ENV, ENV, SHELLOPTS, BASH_FUNC_*, PROMPT_COMMAND, IFS
Per-tool policies registered in one place
Move the per-tool deny lists from the per-tool PRs into src/core/security_policies.rs so adding a new tool is a one-line registry entry.
Tests
tests/security/policy_registry.rs — for every registered tool, instantiate the policy + spawn a no-op and assert env doesn't leak (bash -c 'env | grep ...' style introspection).
Depends on
#34 #35 #36 #37 #39 landing first (or this PR can land first as the scaffolding + others switch to it).
Goal
After the per-tool harden PRs land, the per-tool helpers will have a lot of structural overlap. Generalize into one primitive + one registry, so future tools we wrap inherit defense-in-depth by default.
Architectural shape (from research agent)
Universal env-strip (applied to ALL wrapped tools regardless)
EDITOR,VISUAL,PAGER,LESS,LESSOPEN,LESSCLOSE,MANPAGERLD_PRELOAD,LD_AUDIT,LD_LIBRARY_PATH,DYLD_INSERT_LIBRARIES,DYLD_LIBRARY_PATH,DYLD_FRAMEWORK_PATH,DYLD_FALLBACK_*PERL5OPT,PERL5LIB,LUA_INIT,LUA_PATH,LUA_CPATHBASH_ENV,ENV,SHELLOPTS,BASH_FUNC_*,PROMPT_COMMAND,IFSPer-tool policies registered in one place
Move the per-tool deny lists from the per-tool PRs into
src/core/security_policies.rsso adding a new tool is a one-line registry entry.Tests
tests/security/policy_registry.rs— for every registered tool, instantiate the policy + spawn a no-op and assert env doesn't leak (bash -c 'env | grep ...'style introspection).Depends on
#34 #35 #36 #37 #39 landing first (or this PR can land first as the scaffolding + others switch to it).