Open ThisIsMissEm opened 3 weeks ago
This was discovered via https://github.com/mastodon/mastodon/issues/31395
Interestingly, net.isIPv6('[::]')
also returns false, when I'd expect it to return true
, I think?
@RedYetiDev I believe this affects all net#listen
calls, not just http#listen
@nodejs/net + @nodejs/dns
require('http').createServer((req, res) => {
res.statusCode = 200;
res.end("OK");
}).listen(4001, '[::]');
$ node repro.js
node:events:498
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND [::]
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26)
Emitted 'error' event on Server instance at:
at GetAddrInfoReqWrap.doListen [as callback] (node:net:2130:12)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:17) {
errno: -3008,
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: '[::]'
}
Node.js v22.6.0
This has been reported and discussed before but [::]
is a phrase GitHub's search function doesn't do well on...
[::]
is URL syntax, whereas node's dns, net and http modules expect plain addresses and host names.
I think it should be possible to accept and ignore the brackets without introducing ambiguities. It is however definitely a change in behavior and therefore may have backwards compatibility and/or security implications for downstream users.
Yeah, it could also be ruby/rails which is wrong in using url syntax in their BIND environment variable.
i think automatically stripping brackets with a warning might be okay?
I would not add any specific stripping to this; these kinds of things often end up as attack surfaces for vulnerability hunters. The loopback interface is ::
, not [::]
, use the right one.
Would it be possible to throw a better error here? e.g., an invalid argument error that explains :: vs [::] if the input argument for bind starts with [ ?
I think that would be a very good idea.
I'm not sure where / how I'd do a patch for something like that β it's been far too long since I've contributed to the Node.js codebase.
My attempt to add a general regex check at a higher level is not feasible. The server.listen
method doesn't perform validation on the host parameter; instead, it simply passes it down to the uv
layer for lookup, which is why we're encountering this error. The method relies on the lookup process to reject invalid host values. Currently, it accepts almost any character, and there isn't a straightforward way to implement a high-level guard to cover what is valid domain name and what is not.
For this specific issue, I think it's kind of like a matter of deciding whether/how we want to enforce host validation within server.listen
. I'm hesitant to introduce a check that only targets specific cases, such as []
, but also don't have better idea.
Edit: for reference, ada-url
parses [::]
, which comes back as is, and leave it to uv
to lookup
https://github.com/nodejs/node/blob/885692a34f582c99d74430ba351879431738e43a/src/cares_wrap.cc#L1596
Version
22, 20
Platform
Subsystem
net or dns
What steps will reproduce the bug?
Outputs:
(also reproducible on 22.2.0, same error)
How often does it reproduce? Is there a required condition?
Always
What is the expected behavior? Why is that the expected behavior?
Should listen on all interfaces for ipv6.
What do you see instead?
Server fails to start with an error.
Additional information
Using
bind
of::
works, so the following succeeds:This causes compatibility issues if you've configuration that has a BIND parameter that needs to be passed to Node.js and another process, such as the Ruby on Rails built-in server, which doesn't accept
bind
of::
but does accept[::]