fix(httpclient): enforce tlsServerName certificate verification in Jetty, fail loud in other clients - #7956
Open
GrosQuildu wants to merge 2 commits into
Open
Conversation
GrosQuildu
marked this pull request as ready for review
June 26, 2026 14:33
GrosQuildu
requested review from
ash-thakur-rh,
manusa and
shawkins
as code owners
June 26, 2026 14:33
GrosQuildu
added a commit
to GrosQuildu/kubernetes-client
that referenced
this pull request
Jun 26, 2026
GrosQuildu
force-pushed
the
fix/tls-server-name-cert-verification
branch
from
June 26, 2026 17:14
fdcbe11 to
16ed1a2
Compare
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.
Description
Fabric8 loads kubeconfig
tls-server-nameand passes it to the configured HTTP client builder. Kubernetes uses this field as the expected server certificate name when the URL host is not the Kubernetes API server certificate identity.Fabric8 does not enforce that behavior. JDK, OkHttp, Vert.x, and Vert.x 5 warn that
tlsServerNameis unsupported and continue with normal URL-host verification. Jetty usestlsServerNameonly as Server Name Indication (SNI) inJettyHttpClientBuilder. SNI selects a server certificate on the remote endpoint, but it does not change the client-side certificate hostname verification reference identity.As a result, a Fabric8 client can send Kubernetes credentials to a TLS endpoint whose certificate is valid for the URL host but invalid for the configured
tls-server-name.Exploit Scenario
A CI service uses Fabric8 with a kubeconfig whose cluster URL points at a local tunnel, proxy endpoint, or IP address, and whose
tls-server-namecontains the real Kubernetes API certificate identity. An attacker controls the endpoint reached by the URL host and presents a certificate that is trusted for that URL host but not for the Kubernetes API server name. Fabric8 accepts the TLS connection and sends the caller's Kubernetes credentials to the wrong endpoint.This Java PoC uses Fabric8's Jetty HTTP client and HTTPS mock server. The mock server certificate is trusted by the client and is valid for
localhost, but not forapi.example.cluster.local. The vulnerable behavior is that the request still succeeds and the mock server receives the bearer token.Threat Model
The kubernetes-client sould either fully support SNI (including proper cert validation) or document the current behavior in threat model.
Setting SNI in http clients that do not support it should produce error, not warning. If the warning is to be kept, then this behavior should be documented in threat model.
Other Kubernetes Client Behavior
Other Kubernetes clients that support
tls-server-namebind it to certificate identity verification, not just to server certificate selection:client-gocopies kubeconfigTLSServerNameinto Go'stls.Config.ServerName, which Go uses to verify returned certificates and to send SNI for DNS names.tls-server-nameas urllib3server_hostname; urllib3 verifies TLS against the SNI hostname unless an explicitassert_hostnameoverride is configured.servername; Node's default hostname check uses the explicitly configuredservernamewhen present.HttpRequestMessage.Headers.HostfromTlsServerName; current .NETHttpClientdocumentation states that a custom Host header is used for SNI and affects certificate validation.tls-server-namein OkHttp'sHostnameVerifier, so it checks the certificate against that value even though it does not appear to configure SNI separately.tls-server-name, so it is an unsupported-client data point rather than precedent for SNI-only behavior.This comparison supports the finding: Fabric8's Jetty backend implements only the server-selection half of the field, and the other Fabric8 backends continue after warning that the field is unsupported.
Fix
For backends that cannot enforce
tlsServerNameas the certificate verification identity, fail closed instead of warning and continuing with URL-host verification.For Jetty, keep using
tlsServerNameas SNI and make the JettySSLEngineusetlsServerNameas the peer host. This preserves Java's defaultHTTPSendpoint identification during the TLS handshake, so certificate identity is checked againsttlsServerNamebefore HTTP headers are sent and before a client certificate can be disclosed during mutual TLS when certificate verification is enabled. Do not fix Jetty by only installing aHostnameVerifier: Jetty invokes that verifier after the handshake succeeds, which is too late to protect client-certificate credentials.Paweł Płatek from Trail of Bits in collaboration with OpenAI.