Skip to content

fix(webhook-server): default-bind to loopback instead of 0.0.0.0#2546

Open
smith-vosburg wants to merge 1 commit into
nanocoai:mainfrom
vosburg-auto:fix/webhook-loopback-bind-upstream
Open

fix(webhook-server): default-bind to loopback instead of 0.0.0.0#2546
smith-vosburg wants to merge 1 commit into
nanocoai:mainfrom
vosburg-auto:fix/webhook-loopback-bind-upstream

Conversation

@smith-vosburg
Copy link
Copy Markdown

Type of Change

  • Fix - bug fix or security fix to source code

Description

The webhook server in src/webhook-server.ts currently binds to 0.0.0.0, exposing the HTTP listener to every interface on the host. Most installs don't actually need this — the Chat-SDK Telegram adapter uses long polling, and operators who genuinely need an externally-reachable webhook are typically fronting it with a reverse proxy on a different port anyway.

This refactor extracts resolveListenConfig() so the bind address is environment-driven and unit-testable. Defaults to 127.0.0.1 so the port is not exposed to the LAN; operators who need external exposure can opt in with WEBHOOK_BIND=0.0.0.0 (or a specific interface IP).

Diff

// src/webhook-server.ts
const DEFAULT_BIND = '127.0.0.1';

export function resolveListenConfig(env: NodeJS.ProcessEnv): { port: number; bind: string } {
  const portRaw = env.WEBHOOK_PORT;
  const port = portRaw ? parseInt(portRaw, 10) : DEFAULT_PORT;
  const bind = env.WEBHOOK_BIND || DEFAULT_BIND;
  return { port, bind };
}

// ensureServer():
const { port, bind } = resolveListenConfig(process.env);
// ...
server.listen(port, bind, () => {
  log.info('Webhook server started', { port, bind, adapters: [...routes.keys()] });
});

Tests

src/webhook-server.test.ts (new) — four cases on resolveListenConfig:

  • Default port + loopback when both env vars unset
  • Honors WEBHOOK_PORT when set
  • Honors WEBHOOK_BIND for opt-in external exposure
  • Treats empty-string WEBHOOK_BIND as unset (so an accidental WEBHOOK_BIND= in a dotenv file doesn't silently bind to all interfaces)
Test Files  1 passed (1)
     Tests  4 passed (4)

pnpm typecheck is clean.

Notes

🤖 Generated with Claude Code

Extract resolveListenConfig() so the bind address is environment-driven
and unit-testable. Default to 127.0.0.1 so the webhook port is not
exposed to the LAN; set WEBHOOK_BIND=0.0.0.0 (or a specific interface
IP) to opt back into external exposure.

The existing webhook-server.test.ts imported resolveListenConfig from
the production module, but the symbol had never been extracted — the
test was effectively dead. This commit lands the missing refactor and
extends the test with the empty-string fallback, specific-interface,
and combined-env-var cases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions github-actions Bot added follows-guidelines PR was created using the current contributing template PR: Fix Bug fix labels May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

follows-guidelines PR was created using the current contributing template PR: Fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant