Denial of Service (server crash due to unhandled TLSSocket error during TLS handshake)

HIGH
nodejs/node
Commit: 7d421c8f29a4
Affected: < 25.9.0
2026-04-05 11:12 UTC

Description

The commit adds a default error handler for TLSSocket instances during TLS connection initialization (tlsConnectionListener). Prior to this fix, if a TLS socket emitted an error before the user attached an error handler, it could trigger an unhandled 'error' event, potentially crashing the Node.js process (DoS via crash). The new code attaches a listener for 'error' on the socket (socket.on('error', onSocketTLSError)) to ensure the error is handled even if the application does not attach its own error handler. This resolves a class of denial-of-service scenarios where a misbehaving or abruptly destroyed TLS connection during initialization could crash the server. The patch is tied to CVE-2025-59465 and represents a genuine vulnerability fix rather than a mere dependency bump or test addition.

Proof of Concept

Proof-of-concept to demonstrate the vulnerability before the fix (server could crash when a TLSSocket emits an error with no user-attached error handler): 1) Run a minimal secure HTTP/2 server (pre-fix behavior) and do not attach an error handler to the TLS socket in the 'secureConnection' callback: JavaScript (server.js, pre-fix scenario): const fs = require('fs'); const http2 = require('http2'); const server = http2.createSecureServer({ key: fs.readFileSync('server.key'), cert: fs.readFileSync('server.crt') }); server.on('secureConnection', (socket) => { // Do NOT attach an error handler to the socket here // This is the vulnerable scenario // any error on this socket could crash the process if unhandled }); server.listen(8443, () => console.log('secure server listening on 8443')); 2) Malicious client that triggers a TLS handshake error to produce an unhandled error on the server side: Python client (attempts TLS handshake and then aborts to provoke a server TLS error): import socket, ssl import sys host = '127.0.0.1' port = 8443 s = socket.create_connection((host, port)) # Do not verify certificate; do not complete handshake gracefully ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE try: with ctx.wrap_socket(s, server_hostname=host, do_handshake_on_connect=False) as ssock: # Intentionally do not complete handshake ssock.do_handshake() except Exception as e: print('Client handshake failed (expected):', e) s.close() sys.exit(0) # If the server is vulnerable, this abrupt/failed handshake could emit an error on the # TLSSocket without a user error handler and crash the server. 3) Expected behavior (post-fix): - The server should not crash. The code path now installs a default 'error' listener on TLSSocket, so an error during TLS initialization is handled gracefully by onSocketTLSError, avoiding process exit. Note: In a real test, you would run the server with and without the patch (pre/post fix) and demonstrate that an abrupt handshake error caused a crash in older versions but is suppressed in versions containing this fix.

Commit Details

Author: RafaelGSS

Date: 2025-10-31 19:27 UTC

Message:

lib: add TLSSocket default error handler This prevents the server from crashing due to an unhandled rejection when a TLSSocket connection is abruptly destroyed during initialization and the user has not attached an error handler to the socket. e.g: ```js const server = http2.createSecureServer({ ... }) server.on('secureConnection', socket => { socket.on('error', err => { console.log(err) }) }) ``` PR-URL: https://github.com/nodejs-private/node-private/pull/750 Fixes: https://github.com/nodejs/node/issues/44751 Refs: https://hackerone.com/bugs?subject=nodejs&report_id=3262404 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> CVE-ID: CVE-2025-59465

Triage Assessment

Vulnerability Type: Denial of Service

Confidence: HIGH

Reasoning:

The commit adds a default error handler for TLSSocket to avoid unhandled errors that could crash the server during TLS connection setup when an error handler is not attached. This hardens error handling around TLS sockets and is tied to a CVE, indicating a vulnerability-related fix (denial of service via crash/unhandled error).

Verification Assessment

Vulnerability Type: Denial of Service (server crash due to unhandled TLSSocket error during TLS handshake)

Confidence: HIGH

Affected Versions: < 25.9.0

Code Diff

diff --git a/lib/internal/tls/wrap.js b/lib/internal/tls/wrap.js index 82cf6832c3efa8..1cdfbf0f43fbd3 100644 --- a/lib/internal/tls/wrap.js +++ b/lib/internal/tls/wrap.js @@ -1252,6 +1252,7 @@ function tlsConnectionListener(rawSocket) { socket[kErrorEmitted] = false; socket.on('close', onSocketClose); socket.on('_tlsError', onSocketTLSError); + socket.on('error', onSocketTLSError); } // AUTHENTICATION MODES
← Back to Alerts View on GitHub →