1use std::collections::HashMap;
14
15pub const UNSAFE_ENV_KEYS: &[&str] = &[
21 "LD_PRELOAD",
22 "LD_LIBRARY_PATH",
23 "LD_AUDIT",
24 "LD_DEBUG",
25 "LD_DEBUG_OUTPUT",
26 "DYLD_INSERT_LIBRARIES",
27 "DYLD_LIBRARY_PATH",
28 "DYLD_FALLBACK_LIBRARY_PATH",
29 "DYLD_FRAMEWORK_PATH",
30 "DYLD_FALLBACK_FRAMEWORK_PATH",
31 "DYLD_PRINT_LIBRARIES",
32 "DYLD_FORCE_FLAT_NAMESPACE",
33];
34
35pub fn filter_unsafe_env(env: &HashMap<String, String>) -> (HashMap<String, String>, Vec<String>) {
41 let mut safe = HashMap::with_capacity(env.len());
42 let mut dropped = Vec::new();
43 for (k, v) in env {
44 if is_unsafe_env_key(k) {
45 dropped.push(k.clone());
46 } else {
47 safe.insert(k.clone(), v.clone());
48 }
49 }
50 (safe, dropped)
51}
52
53pub fn is_unsafe_env_key(k: &str) -> bool {
55 UNSAFE_ENV_KEYS
56 .iter()
57 .any(|banned| k.eq_ignore_ascii_case(banned))
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn ld_preload_dropped() {
66 let mut env = HashMap::new();
67 env.insert("LD_PRELOAD".into(), "/tmp/x.so".into());
68 env.insert("PATH".into(), "/usr/bin".into());
69 let (safe, dropped) = filter_unsafe_env(&env);
70 assert!(!safe.contains_key("LD_PRELOAD"));
71 assert_eq!(safe.get("PATH").map(String::as_str), Some("/usr/bin"));
72 assert_eq!(dropped, vec!["LD_PRELOAD".to_string()]);
73 }
74
75 #[test]
76 fn case_insensitive_dyld() {
77 let mut env = HashMap::new();
78 env.insert("dyld_insert_libraries".into(), "/tmp/x.dylib".into());
79 let (safe, dropped) = filter_unsafe_env(&env);
80 assert!(safe.is_empty());
81 assert_eq!(dropped.len(), 1);
82 }
83
84 #[test]
85 fn benign_keys_preserved() {
86 let mut env = HashMap::new();
87 env.insert("HOME".into(), "/home/user".into());
88 env.insert("MY_TOOL_TOKEN".into(), "abc".into());
89 let (safe, dropped) = filter_unsafe_env(&env);
90 assert_eq!(safe.len(), 2);
91 assert!(dropped.is_empty());
92 }
93
94 #[test]
95 fn unsafe_key_check() {
96 assert!(is_unsafe_env_key("LD_PRELOAD"));
97 assert!(is_unsafe_env_key("ld_preload"));
98 assert!(is_unsafe_env_key("DYLD_LIBRARY_PATH"));
99 assert!(!is_unsafe_env_key("PATH"));
100 assert!(!is_unsafe_env_key("LD_PRELOADX"));
101 }
102}