net: reject non-address SocketAddress.parse input - #64832
Conversation
|
Review requested:
|
There was a problem hiding this comment.
This would make the port issue much simpler with this additional validation. If the string ends in /:(\d+)$/, then it can just be sliced off, and if the rest of the string gets parsed as a valid hostname by URLParse then the port can be obtained from the digit string with NumberParseInt.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #64832 +/- ##
=========================================
Coverage 90.07% 90.07%
=========================================
Files 751 755 +4
Lines 254916 256474 +1558
Branches 48133 48520 +387
=========================================
+ Hits 229605 231016 +1411
- Misses 16496 16569 +73
- Partials 8815 8889 +74
🚀 New features to boost your workflow:
|
|
@Renegade334 maybe we should include |
|
I'm not yet convinced this is the best way to approach this (with the regex). Won't block for now but there's probably a more performant / reliable way. |
971d5b4 to
9d21a93
Compare
@jasnell I implemented a new strict socket address parser replacing Ada, it fixes #62906 and is faster. Benchmark results compared to main: |
Signed-off-by: Guilherme Araújo <arauujogui@gmail.com>
9d21a93 to
75ae3d0
Compare
| const common = require('../common.js'); | ||
| const { SocketAddress } = require('net'); | ||
|
|
||
| const inputs = { |
There was a problem hiding this comment.
Those inputs have valid addresses only, can we add others for rejection use case?
|
Benchmark GHA (net / net-socketaddress-parse): https://github.com/nodejs/node/actions/runs/33605572788 |
SocketAddress.parse()no longer builds ahttp://${input}URL and reads the hostname and port back out of the Ada WHATWG URL parser. The input is now split in C++ into host, port and IPv6 zone id, and the host is validated byuv_inet_pton()— the same check theSocketAddressconstructor already used.The Ada URL parser is deliberately lenient about hosts, so
parse()accepted much that is not a socket address: legacy IPv4 forms (0177.0.0.1,0x7f.0.0.1,2130706433,127.1), URL syntax (user@1.2.3.4:80,1.2.3.4:80/foo), and input it rewrites first, such as embedded tabs and non-ASCII digits that IDNA maps to ASCII. Those legacy forms are the ambiguity behind CVE-2021-29923 and CVE-2021-29922. It also disagreed with the constructor, which rejects0177.0.0.1withERR_INVALID_ADDRESS.Separately,
SocketAddress.parse('1.2.3.4:80')returned port 0, because the URL parser drops a port equal to the scheme's default. It now returns 80, fixes #62906.The accepted grammar is documented in
doc/api/net.md. A zone id must be numeric, since libuv resolves one only as an interface name.