diff options
author | Jamie Davis <davisjam@vt.edu> | 2018-04-30 21:27:18 -0400 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2018-06-08 21:35:32 -0700 |
commit | 872c331a930df3e44e8f5db5a90a0383e8d0491b (patch) | |
tree | d0800a6f2ebb433f45d7060f9bed58ec28589d19 /lib/dns.js | |
parent | 8551d311bcbf6c5ebdd544c1409001eb5ba8e26b (diff) | |
download | node-new-872c331a930df3e44e8f5db5a90a0383e8d0491b.tar.gz |
dns: improve setServers() errors and performance
Issue 1: make invalid setServers yield uniform error
Behavior:
dns.setServers throws a null pointer dereference on some inputs.
Expected behavior was the more pleasant
TypeError [ERR_INVALID_IP_ADDRESS] ...
Root cause(s?):
- Dereferencing the result of a regex match without confirming
that there was a match.
- assuming the capture of an optional group (?)
Solution:
Confirm the match, and handle a missing port cleanly.
Tests: I added tests for various unusual inputs.
Issue 2: revise quadratic regex in setServers
Problem:
The IPv6 regex was quadratic.
On long malicious input the event loop could block.
The security team did not deem it a security risk,
but said a PR was welcome.
Solution:
Revise the regex to a linear-complexity version.
Tests:
I added REDOS tests to the "oddities" section.
Fixes: https://github.com/nodejs/node/issues/20441
Fixes: https://github.com/nodejs/node/issues/20443
PR-URL: https://github.com/nodejs/node/pull/20445
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'lib/dns.js')
-rw-r--r-- | lib/dns.js | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/lib/dns.js b/lib/dns.js index 62faf32b69..1f6994ba16 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -289,7 +289,7 @@ function setServers(servers) { // servers cares won't have any servers available for resolution const orig = this._handle.getServers(); const newSet = []; - const IPv6RE = /\[(.*)\]/; + const IPv6RE = /^\[([^[\]]*)\]/; const addrSplitRE = /(^.+?)(?::(\d+))?$/; servers.forEach((serv) => { @@ -309,11 +309,16 @@ function setServers(servers) { } } - const [, s, p] = serv.match(addrSplitRE); - ipVersion = isIP(s); + // addr::port + const addrSplitMatch = serv.match(addrSplitRE); + if (addrSplitMatch) { + const hostIP = addrSplitMatch[1]; + const port = addrSplitMatch[2] || IANA_DNS_PORT; - if (ipVersion !== 0) { - return newSet.push([ipVersion, s, parseInt(p)]); + ipVersion = isIP(hostIP); + if (ipVersion !== 0) { + return newSet.push([ipVersion, hostIP, parseInt(port)]); + } } throw new ERR_INVALID_IP_ADDRESS(serv); |