Repository navigation
Security: do not derive TLS server identity from reverse DNS - #361
Merged
Merged
Conversation
When connecting to a numeric address, getPeerName() returned the host name obtained by a reverse DNS lookup. This name is used for SNI and to verify the server certificate, so an attacker able to spoof the PTR response could make vmime accept a valid certificate for a domain they control. getPeerName() now returns the name as specified when connecting. Certificates are verified against IP addresses in subject alternative names (OpenSSL backend; GnuTLS already does it), and SNI is not sent for IP addresses (RFC 6066).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When connecting to a numeric address (e.g.
203.0.113.5),getPeerName()performed a reverse DNS (PTR) lookup and returned the resulting host name. This name is used both for SNI and as the reference identity when verifying the server certificate.PTR responses are not authenticated. An on-path attacker could intercept the connection, answer the PTR query with a domain they control, and present a valid certificate for that domain: vmime would accept it, and the user's credentials would be sent to the attacker. RFC 6125/9525 forbid deriving the reference identity from an unsecured DNS lookup.
Affected configurations (only when connecting to a numeric address; host names are not affected):
getnameinfo()code path. Before that, thegethostbyaddr()fallback never succeeded, so the numeric address was used.Thanks to @jengelh: #353 made this code path reachable on POSIX, which is how the issue was found (#357 fixed the IPv6 buffer over-read it exposed).
Changes:
getPeerName()now returns the name as specified when connecting, without any reverse DNS lookup (POSIX and Windows).VMIME_HAVE_GETNAMEINFOis no longer needed and has been removed.verifyHostName()now matches IP addresses against IP subject alternative names, usingX509_check_ip_asc(). GnuTLS already does this ingnutls_x509_crt_check_hostname().TLSSocket::isIPAddress()helper.Behavior change: connecting to a numeric address with TLS now requires the server certificate to contain that IP address in its subject alternative names. If the certificate was issued for a host name, connect using the host name (or install a custom
certificateVerifier).