use crate::{EnvVar, Result};
use peek_proc_reader::environ::{read_environ, EnvironEntry};
const SECRET_KEY_PATTERNS: &[&str] = &[
"PASSWORD",
"PASSWD",
"PWD",
"SECRET",
"TOKEN",
"API_KEY",
"APIKEY",
"AUTH",
"CREDENTIAL",
"PRIVATE_KEY",
"ACCESS_KEY",
"AWS_ACCESS_KEY",
"AWS_SECRET",
"DATABASE_URL",
"DB_URL",
"REDIS_URL",
"MONGO_URL",
"DSN",
"SLACK_WEBHOOK",
"WEBHOOK_URL",
];
pub fn collect_env(pid: i32) -> Result<Vec<EnvVar>> {
let raw: Vec<EnvironEntry> = read_environ(pid)?;
let mut vars = Vec::with_capacity(raw.len());
for entry in raw {
let redacted = is_secret(&entry.key, &entry.value);
vars.push(EnvVar {
key: entry.key,
value: if redacted {
"***".to_string()
} else {
entry.value
},
redacted,
});
}
vars.sort_by(|a, b| a.key.cmp(&b.key));
Ok(vars)
}
fn is_secret(key: &str, value: &str) -> bool {
let upper_key = key.to_uppercase();
if SECRET_KEY_PATTERNS.iter().any(|p| upper_key.contains(p)) {
return true;
}
let trimmed = value.trim();
if trimmed.is_empty() {
return false;
}
if trimmed.starts_with("-----BEGIN ") {
return true;
}
if trimmed.starts_with("AKIA") && trimmed.len() >= 16 {
return true;
}
if trimmed.len() >= 40 {
return true;
}
false
}