Skip to content

TLS state leaks for every plain HTTP request on the websocket port #376

Open

Description

@hermannchristopher

For a TLS connection, do_handshake() in common/network/websocket.c creates an SSL_CTX and an SSL. Every early return (each plain HTTP request for a file of the web client, and each refused or failed handshake) frees the connection context with free_ws_ctx() only; just the websocket path calls ws_socket_free(). So each file request over TLS leaks its SSL and SSL_CTX. One page load of the web client is 35 such requests.

Measured on 1.3.2 (kasmweb/chromium:1.16.0): 2000 requests for /package.json grew Xvnc by 75 MB (about 38 KB each); with the change below, by 0.4 MB. The code is the same on master.

The change we ship, against v1.3.2 (ws_socket_free() already sets both pointers to NULL, so nothing is freed twice):

--- a/common/network/websocket.c
+++ b/common/network/websocket.c
@@ -248,6 +248,18 @@ ws_ctx_t *alloc_ws_ctx() {
 }
 
 void free_ws_ctx(ws_ctx_t *ctx) {
+    // The handshake's early returns (plain HTTP requests, refused or failed
+    // handshakes) free the context without ws_socket_free(); release the TLS
+    // state here so a TLS connection does not leak its SSL and SSL_CTX.
+    // ws_socket_free() clears both pointers, so nothing is freed twice.
+    if (ctx->ssl) {
+        SSL_free(ctx->ssl);
+        ctx->ssl = NULL;
+    }
+    if (ctx->ssl_ctx) {
+        SSL_CTX_free(ctx->ssl_ctx);
+        ctx->ssl_ctx = NULL;
+    }
     free(ctx->cin_buf);
     free(ctx->cout_buf);
     free(ctx->tin_buf);

Activity

  1. self-assigned this
    on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions