fix: automation answers can come from NEXUS_ANSWERS instead of argv

--answer puts credentials in the process list and shell history.
NEXUS_ANSWERS (one answer per line) is read at startup and removed from
the environment so local shells don't inherit it, and either source now
prints a warning when used outside --screenshot (SEC-20261012-018).
This commit is contained in:
Andy Dixon
2026-10-12 09:20:31 +01:00
parent b325097602
commit 954bf25dc0
+11 -1
View File
@@ -83,12 +83,22 @@ fn main() -> eframe::Result {
} }
_ => { _ => {
println!( println!(
"usage: nexus-terminal [--theme pro|midnight|light] [--data-dir DIR] [--connect NAME]... [--open WINDOW] [--do PALETTE-COMMAND]... [--answer SECRET]... [--shot-delay MS] [--run-local CMD] [--screenshot out.png] [--size WxH] [--version]" "usage: nexus-terminal [--theme pro|midnight|light] [--data-dir DIR] [--connect NAME]... [--open WINDOW] [--do PALETTE-COMMAND]... [--answer SECRET]... (or NEXUS_ANSWERS=one-per-line) [--shot-delay MS] [--run-local CMD] [--screenshot out.png] [--size WxH] [--version]"
); );
return Ok(()); return Ok(());
} }
} }
} }
// Automation answers: prefer NEXUS_ANSWERS (one per line), which stays out of the process list
// and shell history; it's removed so local shells don't inherit it.
if let Ok(v) = std::env::var("NEXUS_ANSWERS") {
opts.answers.extend(v.lines().map(String::from));
// SAFETY: still single-threaded here; no other thread can be reading the environment.
unsafe { std::env::remove_var("NEXUS_ANSWERS") };
}
if !opts.answers.is_empty() && opts.screenshot.is_none() {
eprintln!("warning: --answer/NEXUS_ANSWERS auto-fill credential prompts; they are meant for screenshot automation only");
}
let config = match data_dir { let config = match data_dir {
Some(d) => { Some(d) => {
let c = AppConfig::in_dir(d.into()); let c = AppConfig::in_dir(d.into());