inspector/clients/cli/src/index.ts
Cliff Hall cea22d86b8
feat(web): enforce localhost-only binding; expand loopback origin allow-list (#1796)
Closes #1795.

Enforce localhost-only binding in code (the "never 0.0.0.0" rule was only a spec note): refuse an all-interfaces HOST — across every spelling the OS binds as the wildcard (inet_aton decimal/octal/hex, IPv6, IPv4-mapped, zone-scoped, IDNA/Unicode) — unless DANGEROUSLY_BIND_ALL_INTERFACES=true (Docker's sanctioned opt-in). Fixes the reported stdio-connect 403 by expanding the default loopback origin allow-list to all three interchangeable forms.

Hardening surfaced across an extended review: closes an IDNA/fullwidth wildcard bypass, a blank-ALLOWED_ORIGINS fail-open, and the CLI/TUI OAuth-callback wildcard bind (loopback-only now, RFC 8252); canonicalizes the origin allow-list the way a browser does; derives frame-ancestors from the real embedder list (IPv6-literal exclusion verified in headless Chromium); strictPort on all three bind points; and preserves the CLI exit-code map + JSON envelope through the mcp-inspector --cli launcher path. Shared host normalization lives in core/node/hostUrl.ts. Docs + tests + smokes throughout.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-26 22:15:10 -04:00

23 lines
809 B
JavaScript

#!/usr/bin/env node
import { resolve } from "path";
import { fileURLToPath } from "url";
import { runCli, validLogLevels } from "./cli.js";
import { handleError } from "./error-handler.js";
// `handleError` is exported so the launcher (which imports `runCli` as a module
// and owns the rejection) can route a `mcp-inspector --cli` failure through the
// CLI's own sink — preserving the EXIT_CODES map and the JSON `{"error":…}`
// envelope that this bin's own `.catch` provides only when run directly.
export { runCli, validLogLevels, handleError };
const __filename = fileURLToPath(import.meta.url);
const isMain =
process.argv[1] !== undefined &&
resolve(process.argv[1]) === resolve(__filename);
if (isMain) {
runCli(process.argv)
.then(() => process.exit(0))
.catch(handleError);
}