Skip to content

Commit a047998

Browse files
authored
Fix TLS certificate validation in Java SDK WebSocket relay connections (#623)
For Sev2.5 31000000590337 The Java SDK's WebSocketConnector used InsecureTrustManagerFactory.INSTANCE for all wss:// relay connections, which bypassed TLS certificate validation entirely. This allowed a man-in-the-middle attacker to intercept the WebSocket handshake, capture the Authorization: tunnel <connect-token> header, and replay the token against a live tunnel to impersonate the client. What changed - WebSocketConnector.java: The SSL context now uses the JDK's default trust manager for production relay connections, which properly validates server certificates against the system's trusted CA store. - Localhost exceptions are preserved for local development (localhost and tunnels.local.api.visualstudio.com), matching the pattern used by the Go SDK.
1 parent a59fd89 commit a047998

1 file changed

Lines changed: 24 additions & 3 deletions

File tree

java/src/main/java/com/microsoft/tunnels/websocket/WebSocketConnector.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import java.net.SocketAddress;
2020
import java.net.URI;
2121

22+
import javax.net.ssl.SSLEngine;
23+
import javax.net.ssl.SSLParameters;
24+
2225
import org.apache.sshd.common.AttributeRepository;
2326
import org.apache.sshd.common.io.IoConnectFuture;
2427
import org.apache.sshd.common.io.IoHandler;
@@ -69,9 +72,27 @@ protected void initChannel(SocketChannel ch) throws Exception {
6972

7073
ChannelPipeline p = ch.pipeline();
7174
if (factory.webSocketUri.getScheme().equals("wss")) {
72-
SslContext sslContext = SslContextBuilder.forClient()
73-
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
74-
p.addLast("ssl", new SslHandler(sslContext.newEngine(ch.alloc())));
75+
String host = factory.webSocketUri.getHost();
76+
boolean isLocalDev = "localhost".equals(host)
77+
|| "tunnels.local.api.visualstudio.com".equals(host);
78+
79+
SslContextBuilder builder = SslContextBuilder.forClient();
80+
if (isLocalDev) {
81+
builder.trustManager(InsecureTrustManagerFactory.INSTANCE);
82+
}
83+
SslContext sslContext = builder.build();
84+
85+
var relayPort = factory.webSocketUri.getPort();
86+
if (relayPort == -1) {
87+
relayPort = 443;
88+
}
89+
SSLEngine engine = sslContext.newEngine(ch.alloc(), host, relayPort);
90+
if (!isLocalDev) {
91+
SSLParameters params = engine.getSSLParameters();
92+
params.setEndpointIdentificationAlgorithm("HTTPS");
93+
engine.setSSLParameters(params);
94+
}
95+
p.addLast("ssl", new SslHandler(engine));
7596
}
7697
p.addLast(new HttpClientCodec());
7798
p.addLast(new HttpObjectAggregator(8192));

0 commit comments

Comments
 (0)