From a288f3066fde98d0312f1201072bec8189c8d303 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 26 Feb 2026 12:11:12 +0000 Subject: [PATCH] fix(gateway): warn on non-loopback bind at startup (land #25397, thanks @let5sne) Co-authored-by: let5sne --- CHANGELOG.md | 1 + src/gateway/server-runtime-state.ts | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57862c972c3..13ba26ea61e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai - Security/Exec approvals forwarding: prefer turn-source channel/account/thread metadata when resolving approval delivery targets so stale session routes do not misroute approval prompts. - Onboarding/Gateway: seed default Control UI `allowedOrigins` for non-loopback binds during onboarding (`localhost`/`127.0.0.1` plus custom bind host) so fresh non-loopback setups do not fail startup due to missing origin policy. (#26157) thanks @stakeswky. - CLI/Gateway status: force local `gateway status` probe host to `127.0.0.1` for `bind=lan` so co-located probes do not trip non-loopback plaintext WebSocket checks. (#26997) thanks @chikko80. +- Gateway/Bind visibility: emit a startup warning when binding to non-loopback addresses so operators get explicit exposure guidance in runtime logs. (#25397) thanks @let5sne. - Auto-reply/Streaming: suppress only exact `NO_REPLY` final replies while still filtering streaming partial sentinel fragments (`NO_`, `NO_RE`, `HEARTBEAT_...`) so substantive replies ending with `NO_REPLY` are delivered and partial silent tokens do not leak during streaming. (#19576) Thanks @aldoeliacim. - Doctor/State integrity: ignore metadata-only slash routing sessions when checking recent missing transcripts so `openclaw doctor` no longer reports false-positive transcript-missing warnings for `*:slash:*` keys. (#27375) thanks @gumadeiras. - Channels/Multi-account config: when adding a non-default channel account to a single-account top-level channel setup, move existing account-scoped top-level single-account values into `channels..accounts.default` before writing the new account so the original account keeps working without duplicated account values at channel root; `openclaw doctor --fix` now repairs previously mixed channel account shapes the same way. (#27334) thanks @gumadeiras. diff --git a/src/gateway/server-runtime-state.ts b/src/gateway/server-runtime-state.ts index af42df0fc42..c9fa334222e 100644 --- a/src/gateway/server-runtime-state.ts +++ b/src/gateway/server-runtime-state.ts @@ -11,7 +11,7 @@ import type { ResolvedGatewayAuth } from "./auth.js"; import type { ChatAbortControllerEntry } from "./chat-abort.js"; import type { ControlUiRootState } from "./control-ui.js"; import type { HooksConfigResolved } from "./hooks.js"; -import { resolveGatewayListenHosts } from "./net.js"; +import { isLoopbackHost, resolveGatewayListenHosts } from "./net.js"; import { createGatewayBroadcaster, type GatewayBroadcastFn, @@ -117,6 +117,12 @@ export async function createGatewayRuntimeState(params: { }); const bindHosts = await resolveGatewayListenHosts(params.bindHost); + if (!isLoopbackHost(params.bindHost)) { + params.log.warn( + "⚠️ Gateway is binding to a non-loopback address. " + + "Ensure authentication is configured before exposing to public networks.", + ); + } const httpServers: HttpServer[] = []; const httpBindHosts: string[] = []; for (const host of bindHosts) {