[HIGH] Enforce TLS peer and hostname verification - #62
Open
OskarEichler wants to merge 1 commit into
Open
Conversation
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.
Summary
Enable OpenSSL's secure client defaults for every HTTPS connection and verify the TLS origin hostname, including connections tunneled through an HTTP proxy. This prevents untrusted endpoints from impersonating the requested HTTPS server.
Security impact and urgency
HIGH.
NetHttp2::Clientcurrently constructs anOpenSSL::SSL::SSLContextwithout callingset_params. Ruby's default context hasverify_mode == VERIFY_NONEand hostname verification disabled, so HTTPS connections accept self-signed or otherwise untrusted certificates. A network-positioned attacker, poisoned DNS response, or malicious proxy can terminate TLS, read request headers and bodies, capture bearer credentials, and forge responses with the application's network privileges.This affects both the default context and caller-provided contexts that do not explicitly enable verification. Apnotic uses both paths for Apple Push Notification connections, including bearer-token authentication.
Reproduction
A focused local TLS server presents a fresh self-signed certificate that is absent from the client's trust store. Current 0.19.0/current master accepts it and reports:
The final values are
verify_modeandverify_hostname. With this patch, the same peer is rejected withcertificate verify failed (self-signed certificate). Adding that certificate to a customX509::Storesucceeds and reports:Implementation
SSLContext#set_paramsfor HTTPS contexts, enabling certificate-chain and hostname verification plus the platform trust store.SSLSocket#hostnameto the requested origin. For a CONNECT proxy, TLS terminates at the origin through the tunnel, so using the proxy address for SNI/verification is incorrect. This also resolves the hostname problem reported in Proxy not working #30.Verification
VERIFY_PEER, hostname verification, and the Apple APNs origin on Ruby 4.0.6.api.push.apple.com:443succeeds with TLS 1.3 andverify_result == 0; no APNs request or production operation was performed.gem build net-http2.gemspecsucceeds for 0.19.0.git diff --checkpasses.Limitations
The local model covers trust-chain and hostname-verification configuration, not every TLS version, cipher, operating-system trust store, proxy implementation, or network failure mode. The live check validates only a TLS handshake. Existing ALPN, proxy I/O, timeout, and stream-lifecycle issues are outside this focused fix.
Breaking-change note
HTTPS endpoints using self-signed or privately issued certificates will now fail unless their CA is explicitly added to a custom context's
cert_store. Callers that deliberately relied on unauthenticated TLS must configure trust instead. Proxied TLS now sends and verifies the origin hostname rather than the proxy address.