From 954bf25dc0ff4a6bd97a5bf9bdcbf02a509a594a Mon Sep 17 00:00:00 2001 From: Andy Dixon Date: Mon, 12 Oct 2026 09:20:31 +0100 Subject: [PATCH] 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). --- rust/app/src/main.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/rust/app/src/main.rs b/rust/app/src/main.rs index 7240a6e..d84ebcc 100644 --- a/rust/app/src/main.rs +++ b/rust/app/src/main.rs @@ -83,12 +83,22 @@ fn main() -> eframe::Result { } _ => { 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(()); } } } + // 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 { Some(d) => { let c = AppConfig::in_dir(d.into());