fix(httpclient): apply proxy settings to Jetty and Vertx-5 WebSocket clients - #7949
Open
GrosQuildu wants to merge 3 commits into
Open
fix(httpclient): apply proxy settings to Jetty and Vertx-5 WebSocket clients#7949GrosQuildu wants to merge 3 commits into
GrosQuildu wants to merge 3 commits into
Conversation
GrosQuildu
requested review from
ash-thakur-rh,
manusa and
shawkins
as code owners
June 26, 2026 13:49
GrosQuildu
added a commit
to GrosQuildu/kubernetes-client
that referenced
this pull request
Jun 26, 2026
Add a shared behavioral test that opens a WebSocket with an HTTP proxy configured and asserts the proxy receives the CONNECT tunnel request. Wire the shared test into the JDK, OkHttp, Vert.x 4, Vert.x 5, and Jetty client modules.
GrosQuildu
force-pushed
the
ptp-66-websocket-proxy-settings
branch
from
June 26, 2026 17:14
7f0eeb4 to
d1d110f
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 applies configured proxy settings to the ordinary HTTP clients in the Jetty and Vert.x 5 transport modules, but both modules create separate WebSocket clients and left those WebSocket clients without the same proxy configuration.
In
httpclient-jetty,JettyHttpClientBuilder.build()createssharedHttpClientand a separateWebSocketClientbacked by its own JettyHttpClient. The proxy switch addedHttpProxy,Socks4Proxy, orSocks5Proxyonly tosharedHttpClient.getProxyConfiguration(). The backingsharedWebSocketClient.getHttpClient()remained direct.In
httpclient-vertx-5,Vertx5HttpClientBuilder.build()calledapplyProxy(httpOptions)forWebClientOptions, then created independentWebSocketClientOptionswithout applying proxy options to them.Fabric8 uses WebSockets for credential-bearing Kubernetes operations including pod exec, attach, port-forward, upload/copy paths that run over exec, and WebSocket watches. As a result, a caller can configure a proxy expecting all Kubernetes API traffic to traverse an approved egress route or audit point, but WebSocket-backed operations with these two transports connect directly to the API server when direct network access is available.
The other production HTTP transports do not have this split-client omission. The JDK transport configures the proxy on
java.net.http.HttpClientand creates WebSockets withgetHttpClient().newWebSocketBuilder(). The OkHttp transport configures the proxy on the sharedOkHttpClientand creates WebSockets with that same client. The Vert.x 4 transport sets proxy options on the single Vert.xHttpClientand opens WebSockets through that client. The vulnerable pattern is specific to Jetty and Vert.x 5 because they build separate WebSocket client objects whose proxy options were not populated.Exploit Scenario
An organization requires Kubernetes API traffic from controller processes to pass through an internal proxy for network allowlisting and audit logging. A controller built with Fabric8 uses the Jetty or Vert.x 5 HTTP client and sets an HTTP proxy through the normal client configuration.
Regular resource CRUD requests honor the proxy. Later, the controller performs
pod.exec,attach,portForward, or a WebSocket watch. Those WebSocket upgrade requests are built from separate WebSocket clients whose proxy settings were never populated, so the process opens a direct connection to the Kubernetes API server with the same credentials and bypasses the organization's proxy policy.Threat Model
This is just a regular bug.
Fix
Apply the selected proxy type, address, and proxy authentication to Jetty's WebSocket backing
HttpClientand to Vert.x 5WebSocketClientOptions.Keep the existing Jetty and Vert.x 5 builder/configuration tests, and add the shared
AbstractHttpClientWebSocketProxyTestsubclasses so all production HTTP clients must continue to route WebSocket tunnel setup through the configured HTTP proxy.The shared test starts a mock HTTP proxy and configures the client under test to use it. It then opens a WebSocket through
client.newWebSocketBuilder()to anhttps://127.0.0.1:<unused-port>/proxied-websockettarget. The target port is closed, so the only successful observable route is the configured proxy. The test passes only when the mock proxy receives the expectedCONNECT 127.0.0.1:<unused-port>tunnel request. Vulnerable WebSocket clients connect directly to the closed loopback port, so the mock proxy sees noCONNECTand the test times out.Negative validation on current
mainwith the new behavioral test added:./mvnw -B -ntp -pl httpclient-jetty -am -DskipITs \ -Dsurefire.failIfNoSpecifiedTests=false \ -Dtest=JettyHttpClientWebSocketProxyTest testResult:
./mvnw -B -ntp -pl httpclient-vertx-5 -am -DskipITs \ -Dsurefire.failIfNoSpecifiedTests=false \ -Dtest=Vertx5HttpClientWebSocketProxyTest testResult:
Positive validation on the patched PR branch:
Result:
Paweł Płatek from Trail of Bits in collaboration with OpenAI.