Loading HuntDB...

DNS rebinding in --inspect (insufficient fix of CVE-2022-32212 affecting macOS devices)

High
N
Node.js
Submitted None
Reported by zeyu2001

Vulnerability Details

Technical details and impact analysis

Improper Access Control - Generic
**Summary:** This is an insufficient fix of CVE-2022-32212, which itself is a fix of CVE-2018-7160. There exists a specific behaviour in browsers on macOS devices when handling the `http://0.0.0.0`URL that allows an attacker-controlled DNS server to bypass the DNS rebinding protection by resolving hosts in the `.local` domain. **Description:** In the latest version, only IP addresses and `localhost` are allowed in the `Host` header when connecting to the debugger endpoint. `IsIPAddress` ensures that IPv4 address octets only contain values ranging from 0 to 255, but this allows `0.0.0.0` [which indicates an invalid or unroutable target](https://en.wikipedia.org/wiki/0.0.0.0). In macOS devices, using `fetch("http://0.0.0.0")`or opening `http://0.0.0.0` through a top-level navigation in Chrome and Firefox will cause a DNS request to resolve `<Computer Name>.local`, where Computer Name is configured in the system preferences (the use of the `.local` TLD is a known [feature](https://blog.scottlowe.org/2006/01/04/mac-os-x-and-local-domains) of macOS devices). If such a request succeeds, `http://0.0.0.0` is routed to the IP address provided in the DNS reply. This would typically be the same as the IP address of the device on the local network, so `http://0.0.0.0` will typically route to any application listening on the local interface - working as intended. An attacker-controlled DNS server can, however, resolve `<Computer Name>.local` to any arbitrary IP address, and consequently cause the victim's browser to load arbitrary content at `http://0.0.0.0`. This allows the attacker to bypass the DNS rebinding protection. Note: On Windows devices, `http://0.0.0.0` is treated as an invalid URL and the request is blocked. ## Steps To Reproduce: ### General Attack Flow 1. Victim runs node with --inspect option 2. Victim visits attacker's webpage 3. The attacker's webpage opens `http://0.0.0.0:9229` 4. Victim asks the DNS server for `<Computer Name>.local` and gets <attacker's-IP>. 5. Victim loads webpage `http://0.0.0.0:9229` from <attacker's-IP>. 6. The webpage `http://0.0.0.0:9229` tries to load `http://0.0.0.0:9229/json`. 7. Due to a short TTL, the DNS server will be soon asked again about an entry for `<Computer Name>.local`. This time, the DNS server responds with "127.0.0.1". 8. The `http://0.0.0.0:9229` website (i.e., the one hosted on <attacker's IP>) will retrieve `http://0.0.0.0:9229/json` from 127.0.0.1, including webSocketDebuggerUrl. 9. Now, the attacker knows the webSocketDebuggerUrl and can connect to it 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 segment: https://github.com/nodejs/node/blob/d9b71f4c241fa31cc2a48331a4fc28c15937875a/src/inspector_socket.cc#L164-L183 ### DNS Setup In this example I used [dnsmasq](https://thekelleys.org.uk/dnsmasq/doc.html) as my DNS server. You can use {F1816108} for a minimal Docker setup that demonstrates the arbitrary resolution of `<Computer Name>.local` domains. The `hosts` file should be changed according to the configured Computer Name of the victim device (through system preferences). For example, my Computer Name is `Zeyu’s MacBook Pro`, which means I had the `Zeyus-Macbook-Pro.local` domain. ``` # Resolve <Computer Name>.local to any IP address 1.1.1.1 Zeyus-Macbook-Pro.local ``` When connecting to `http://0.0.0.0`, the page is loaded from `1.1.1.1` instead. {F1816116} If you observe the network traffic while connecting to `http://0.0.0.0`, you should see the relevant DNS requests and replies. {F1816134} Subsequently `<Computer Name>.local` can be rebinded to `127.0.0.1`, causing the page to be loaded from `127.0.0.1` where the debugger is listening. {F1816125} ## Suggested Remediation [According to IANA](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml), `0.0.0.0/8` is a reserved address range. To prevent this vulnerability, this address range could be blocked. A way to check for this address range could simply be `accum == 0` in the first octet or `host.front() == '0'` in [IsIPAddress](https://github.com/nodejs/node/blob/d9b71f4c241fa31cc2a48331a4fc28c15937875a/src/inspector_socket.cc#L164-L183) ## Supporting Material/References: - Original vulnerability: https://nvd.nist.gov/vuln/detail/CVE-2018-7160 - Code segment: https://github.com/nodejs/node/blob/d9b71f4c241fa31cc2a48331a4fc28c15937875a/src/inspector_socket.cc#L164-L183 ## Impact Attacker with access to a compromised DNS server or the ability to spoof its responses can gain access to the Node.js debugger, which can result in remote code execution.

Related CVEs

Associated Common Vulnerabilities and Exposures

A OS Command Injection vulnerability exists in Node.js versions <14.20.0, <16.20.0, <18.5.0 due to an insufficient IsAllowedHost check that can easily be bypassed because IsIPAddress does not properly check if an IP address is invalid before making DBS requests allowing rebinding attacks.

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

Submitted

Weakness

Improper Access Control - Generic