DNS rebinding in --inspect (insufficient fix of CVE-2018-7160)
High
N
Node.js
Submitted None
Actions:
Reported by
v6ak
Vulnerability Details
Technical details and impact analysis
**Summary:** While the debugger (i.e., the --inspect option) tries to prevent DNS rebinding, the whitelist is excessive.
**Description:** The whitelist includes “localhost6”, which is not that widespread. When “localhost6” is not present in /etc/hosts, it is just an ordinary domain that is resolved via DNS, i.e., over network. If the attacker controls victim's DNS server or can spoof its responses, the DNS rebinding protection can be bypassed by using the “localhost6” domain. As long as the attacker uses the “localhost6” domain, they can still apply the attack described in CVE-2018-7160.
Reasoning why localhost6 is not so common and Node.js should not rely on its presence in the hosts file:
* It is not even present in the node:latest Docker image (sha256:aa1930b56896a43dedb227526d5d40f4a6e9157f9d8703f9584650cde510438a)
* I haven't seen it in Windows 10.
* Unlike RFC 6761 for localhost, I have found no RFC that mentions localhost6 (see https://www.google.com/search?q=localhost6+site%3Atools.ietf.org ).
## Steps To Reproduce:
Preconditions: Victim has no entry for localhost6 in hosts and attacker controls DNS responses. (It does not matter if the attacker control the DNS server or the network communication between the DNS server and the victim.)
1. Victim runs node with --inspect option
2. Victim visits attacker's webpage
3. The attacker's webpage opens http://localhost6:9229
4. Victim finds no “localhost6” entry in hosts file, so it asks the DNS server and gets <attacker's-IP>. (Maybe the response will have a short TTL. There are multiple tricks to make DNS rebinding successful in a short time, but I am not going to be exhaustive.)
5. Victim loads webpage http://localhost6:9229 from <attacker's-IP>.
6. The webpage http://localhost6:9229 tries to load http://localhost6:9229/json from attacker's server. (If the IP address of “localhost6” is still cached, attacker needs to retry. There are techniques that can speed it up, like using RST packet.)
7. Due to a short TTL, the DNS server will be soon asked again about an entry for “localhost6”. This time, the DNS server responds “127.0.0.1”.
8. The http://localhost6:9229 website (i.e., the one hosted on <attacker's IP>) will retrieve http://localhost6:9229/json from 127.0.0.1, including webSocketDebuggerUrl.
9. Now, the attacker knows the webSocketDebuggerUrl and can connect to is using WebSocket. Note that WebSocket is not restricted by same-origin-policy. By doing so, they can gain the privileges of the Node.js instance.
Vulnerable code: https://github.com/nodejs/node/blob/fdf0a84e826d3a9ec0ce6f5a3f5adc967fe99408/src/inspector_socket.cc#L584
## Impact:
Attacker can gain access to the Node.js debugger, which can result in remote code execution.
## Supporting Material/References:
* Original vulnerability: https://nvd.nist.gov/vuln/detail/CVE-2018-7160
* Vulnerable code: https://github.com/nodejs/node/blob/fdf0a84e826d3a9ec0ce6f5a3f5adc967fe99408/src/inspector_socket.cc#L584
* Documentation that mentions the vulnerable behavior: https://nodejs.org/en/docs/guides/debugging-getting-started/
## Impact
Attacker can gain access to the Node.js debugger, which can result in remote code execution.
Related CVEs
Associated Common Vulnerabilities and Exposures
CVE-2018-7160
UNKNOWN
The Node.js inspector, in 6.x and later is vulnerable to a DNS rebinding attack which could be exploited to perform remote code execution. An attack is possible from malicious websites open in a web browser on the same computer, or another computer with network access to the computer running the …
Report Details
Additional information and metadata
State
Closed
Substate
Resolved
Bounty
$500.00
Submitted
Weakness
Improper Access Control - Generic