# Node.js: TLS session reuse can lead to hostname verification bypass

Node.js emits 'session' events before hostname verification, letting an invalid-cert session be cached and reused to bypass hostname checks on later HTTPS requests.

- Payout: hidden
- Severity: high
- Program: Node.js
- Found by: fwilhelm
- Disclosed: 2020-06-03
- CVE: CVE-2020-8172
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/811502
- Library page: https://bugbountylibrary.com/r/h1%3A811502
- Tags: area:devices domain:network impact:integrity kind:bounty platform:hackerone sev:high tech:nodejs technique:race-window technique:source-review vuln:auth-bypass vuln:race-condition

**Target:** Node.js TLS/HTTPS client session cache
**Root cause:** The 'session' event fires from OpenSSL get_session_cb regardless of onConnectSecure hostname verification result, so sessions from invalid-cert handshakes enter the https agent session cache before eviction on socket error.
**Steps:**
1. Attacker MITMs a TLS connection to a host with a CA-signed cert for a different hostname (e.g. loca.host) and supports resumption.
2. Victim's first request fails hostname verification but the 'session' event still fires and caches the session under the agent key.
3. Before the socket 'close' error evicts the session, a second request to the same host reuses the cached session.
4. Resumed session skips checkServerIdentity because isSessionReused() is true, so the second request succeeds against the attacker's server (`Bypassed hostname verification. Server response: 200`).
**How found:** Reading the tls docs noting sessions 'can be used immediately or later', then tracing that get_session_cb fires independently of onConnectSecure and that the https agent caches on 'session' but only evicts on socket close error, revealing a race window.
**Exploitation:** MITM position plus a server with any CA-signed cert and TLS resumption support; race the session cache eviction window with a second request to the same host to get a verified-looking connection to the attacker.
**Insight:** When a security check and a cache-population callback are driven by different OpenSSL callbacks, check ordering per TLS version (1.2 vs 1.3) and whether eviction is tied to a later error event; a cache populated before verification can outlive the failure.

