Does Node.js server.listen() without a host argument always bind to all interfaces, and is localhost-only binding still opt-in?
0 reputation · 04 Sept 2024, 18:33 UTC
0 reputation · 04 Sept 2024, 18:33 UTC
I'm reviewing the network exposure defaults for a Node.js service built on the documented http.createServer().listen(port[, host]) API. My understanding is that omitting the host argument binds to all available IPv4 and IPv6 addresses (0.0.0.0 and ::), which means a service can become reachable from external networks unless a firewall blocks it. I want to confirm the exact scope of this behavior before writing binding configuration guidance.
The constraints: the service must run in both local development (where localhost-only is preferred) and in containers (where binding to all interfaces is required for port publishing). I would rather not rely on developers remembering to pass 127.0.0.1 explicitly, and I am unsure whether the same default applies uniformly across HTTP, HTTPS, and raw TCP servers, or whether any recent LTS line changed it.
My questions:
http, https, and net servers in the current LTS lines (v18.x, v20.x), or are there documented exceptions?--inspect debugger flag follow the same default binding, and is restricting it purely a host-argument concern?listen() call pass the host explicitly?When the host argument is omitted from server.listen(port[, host][, backlog][, callback]), Node.js binds to all configured IPv4 and IPv6 addresses (0.0.0.0 and ::) for http, https, and net servers. This default is identical across the current LTS lines (v18.x and v20.x) and has not changed.
The Node.js inspector (--inspect or --inspect-brk) behaves differently: it binds only to the loopback interface (127.0.0.1:9229 for IPv4 and ::1:9229 for IPv6 when IPv6 is enabled) unless an explicit host:port is supplied after the equals sign.
There is no built‑in process‑wide mechanism (environment variable, command‑line flag, or runtime setting) that alters the default host used by listen(). Each call must specify the desired host if a non‑default binding is required.
test.js):
const http = require('http');
const server = http.createServer((req, res) => { res.end('ok'); });
server.listen(3000); // no host argument
console.log('Listening on port 3000');
node test.js.ss -ltnp | grep :3000netstat -tlnp | grep :30000.0.0.0:3000 and, if IPv6 is enabled, :::3000.node --inspect=9229 test.js and run the same socket check for port 9229. You will see only 127.0.0.1:9229 (and ::1:9229 when IPv6 is enabled).Please confirm whether IPv6 is enabled on your target system, as this determines whether the dual‑stack output includes the :: address.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.