Skip to content

fix: Pass host to tls.connect for certificate validation - #3756

Open
jhnns wants to merge 1 commit into
brianc:masterfrom
jhnns:fix-ip-tls-validation
Open

fix: Pass host to tls.connect for certificate validation#3756
jhnns wants to merge 1 commit into
brianc:masterfrom
jhnns:fix-ip-tls-validation

Conversation

@jhnns

@jhnns jhnns commented Aug 24, 2026

Copy link
Copy Markdown

Continues #2273 by @RazerM (with tests, as requested in this comment). Fixes #2263.

The problem

When connecting with ssl enabled, pg hands an already-connected socket to tls.connect(), so Node.js validates the server certificate against:

options.servername || options.host || 'localhost'

pg only sets servername for hostnames, since SNI must not contain IP addresses (RFC 6066, section 3 — the reason for the check introduced in #1890). But servername was doing double duty as the name for certificate validation, and host was never set. So when connecting to an IP address, the certificate was silently validated against 'localhost' — a certificate for an entirely different server would be accepted (see #2263).

The fix

Also pass host to tls.connect(). Node.js then validates the certificate against the IP being connected to (via its IP SANs). Hostname connections are unaffected (servername still takes precedence), as are Unix domain sockets (host is undefined there, as before). Per Node's docs, host is ignored except for certificate validation when a socket is supplied. Both sides are now documented with code comments in upgradeToSSL.

Tests

Added test/unit/connection/ssl-tests.js, following the existing unit-test conventions:

  1. Connecting to an IP address passes host to the secure stream and leaves servername unset.
  2. Connecting to a hostname passes both host and servername.
  3. An end-to-end test performing a real TLS handshake agar (using the existing test/tls certificates), assertingvia a checkServerIdentity override that Node.js verifies the certificate against the IP address. Without the fix, it receives 'localhost' and the test fails.

…P address

tls.connect verifies the server identity against `servername`, falling
back to `host` and then to 'localhost'. Since `servername` must not be
set to an IP address (RFC 6066 section 3), certificates were validated
against 'localhost' whenever the connection host was an IP address.
Passing `host` to tls.connect fixes this.

Continues brianc#2273 (originally by Frazer McLean) with tests.

Fixes brianc#2263

Co-authored-by: Frazer McLean <frazer@frazermclean.co.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IP hosts are not validated correctly against certificate altnames

1 participant