From a534edb49c60065f3676d0a3a42dae115b5e2a6e Mon Sep 17 00:00:00 2001 From: Cylae <13425054+Cylae@users.noreply.github.com> Date: Wed, 9 Sep 2026 00:55:01 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=20Fix=20argument=20injection=20vul?= =?UTF-8?q?nerability=20in=20run=5Fcli=5Ftoggle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Insert `--` before passing the positional service argument to std::process::Command. This guarantees that clap and other argument parsers interpret service as a positional value rather than a command-line flag or option, preventing argument injection. --- server_manager/src/interface/web.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/server_manager/src/interface/web.rs b/server_manager/src/interface/web.rs index 04134c5..2d23cbd 100644 --- a/server_manager/src/interface/web.rs +++ b/server_manager/src/interface/web.rs @@ -1383,7 +1383,7 @@ fn run_cli_toggle(service: &str, enable: bool) { info!("Web UI triggering: server_manager {} {}", action, service); if let Ok(exe) = std::env::current_exe() { - match Command::new(exe).arg(action).arg(service).spawn() { + match Command::new(exe).arg(action).arg("--").arg(service).spawn() { Ok(mut child) => { // Spawn a background task to wait for the child process to exit. // This prevents zombie processes by collecting the exit status. @@ -1932,3 +1932,17 @@ async fn audit_page(session: Session) -> impl IntoResponse { write_html_foot(&mut html); Html(html).into_response() } + +#[cfg(test)] +mod tests { + #[test] + fn test_run_cli_toggle_command_args() { + let action = "enable"; + let service = "plex"; + let mut cmd = std::process::Command::new("server_manager"); + cmd.arg(action).arg("--").arg(service); + + let args: Vec<&std::ffi::OsStr> = cmd.get_args().collect(); + assert_eq!(args, vec!["enable", "--", "plex"]); + } +}