From f8d06b01441c2c297ea857ebff37d9c2f68faf12 Mon Sep 17 00:00:00 2001 From: cyq <15000851237@163.com> Date: Fri, 19 Jun 2026 18:36:07 +0800 Subject: [PATCH] fix(app-server): require auth for non-loopback binds Signed-off-by: cyq <15000851237@163.com> --- crates/app-server/src/lib.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/crates/app-server/src/lib.rs b/crates/app-server/src/lib.rs index 17ef5b47f..85298207b 100644 --- a/crates/app-server/src/lib.rs +++ b/crates/app-server/src/lib.rs @@ -401,6 +401,10 @@ fn resolve_auth_token(options: &AppServerOptions) -> Result> { return Ok(None); } + if configured.is_none() && !options.listen.ip().is_loopback() { + bail!("refusing app-server bind on non-loopback address without explicit auth token"); + } + let token = configured .map(str::to_string) .unwrap_or_else(|| format!("cwapp_{}", Uuid::new_v4().simple())); @@ -1400,6 +1404,23 @@ mod tests { assert!(token.unwrap().starts_with("cwapp_")); } + #[test] + fn non_loopback_bind_without_explicit_auth_token_fails_fast() { + let options = AppServerOptions { + listen: "0.0.0.0:8787".parse().expect("addr"), + config_path: None, + auth_token: None, + insecure_no_auth: false, + cors_origins: Vec::new(), + }; + + let err = resolve_auth_token(&options).expect_err("non-loopback bind must require auth"); + assert!( + err.to_string().contains("explicit auth token"), + "error should explain that non-loopback binds need explicit auth; got {err}" + ); + } + #[test] fn auth_token_explicit_is_preserved() { let options = AppServerOptions {