12.12 Environment Variable Security
Bash commands often include environment variable assignment prefixes (e.g., NODE_ENV=production npm start). The permission system needs to handle these variables correctly, otherwise two problems arise:
- Matching problem: If safe environment variables are not stripped,
NODE_ENV=prod npm testcannot match theBash(npm test:*)rule - Security problem: If dangerous environment variables are stripped,
LD_PRELOAD=/evil.so npm testwould be incorrectly matched as the safenpm test
Safe Variable Allowlist
The following environment variables are stripped before permission matching (they only affect program behavior, not code execution):
| Category | Variables | Purpose |
|---|---|---|
| Go | GOOS, GOARCH, CGO_ENABLED, GO111MODULE, GOEXPERIMENT | Build target, module mode |
| Rust | RUST_BACKTRACE, RUST_LOG | Debug output level |
| Node | NODE_ENV | Runtime mode (development/production) |
| Python | PYTHONUNBUFFERED, PYTHONDONTWRITEBYTECODE | Output buffering, bytecode |
| Terminal | TERM, COLORTERM, NO_COLOR, FORCE_COLOR | Terminal type, color support |
| i18n | LANG, LANGUAGE, LC_ALL, LC_CTYPE, etc. | Language and character set |
| Other | TZ, LS_COLORS, GREP_COLORS | Timezone, color scheme |
Dangerous Variable Blocklist
The following variables are never stripped—they remain in the command for permission matching, because they can affect code execution:
| Variable | Danger |
|---|---|
PATH | Controls which binary gets executed—PATH=/evil:$PATH cmd lets the attacker's cmd execute first |
LD_PRELOAD | Injects shared libraries into any process—can hijack any system call |
LD_LIBRARY_PATH | Changes dynamic library search path |
DYLD_* | macOS dynamic linker variables, similar to LD_PRELOAD |
NODE_OPTIONS | Can include --require /evil.js, executing arbitrary code when a Node process starts |
PYTHONPATH | Controls Python module search path—can load malicious modules |
NODE_PATH | Controls Node module search path |
CLASSPATH | Controls Java class search path |
GOFLAGS, RUSTFLAGS | Inject arbitrary flags into the compiler |
BASH_ENV | Specifies a script that automatically executes when non-interactive Bash starts |
Design principle: If a variable can affect code execution or library loading, it must not be stripped. It is better to have false positives (safe commands requiring confirmation) than false negatives (dangerous commands being auto-allowed).
Source:
src/tools/BashTool/bashPermissions.ts,stripSafeWrappersandSAFE_ENV_VARSrelated code