From 84db7a9eae8468c0445b15aa806fa7fa806fa0f2 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 8 Sep 2025 14:14:15 +0200
Subject: [PATCH] ws: get a new mask for each new outgoing frame

Reported-by: Calvin Ruocco
Closes #18496
---
 lib/ws.c | 28 +++++++++++++---------------
 1 file changed, 13 insertions(+), 15 deletions(-)

Index: curl-8.0.1/lib/ws.c
===================================================================
--- curl-8.0.1.orig/lib/ws.c
+++ curl-8.0.1/lib/ws.c
@@ -153,8 +153,7 @@ CURLcode Curl_ws_accept(struct Curl_easy
   if(result)
     return result;
 
-  infof(data, "Received 101, switch to WebSocket; mask %02x%02x%02x%02x",
-        ws->ws.mask[0], ws->ws.mask[1], ws->ws.mask[2], ws->ws.mask[3]);
+  infof(data, "Received 101, switch to WebSocket");
   Curl_dyn_init(&wsc->early, data->set.buffer_size);
   if(nread) {
     result = Curl_dyn_addn(&wsc->early, mem, nread);
@@ -557,6 +556,8 @@ static size_t ws_packethead(struct Curl_
   unsigned char firstbyte = 0;
   int outi;
   unsigned char opcode;
+  CURLcode result;
+
   if(flags & CURLWS_TEXT) {
     opcode = WSBIT_OPCODE_TEXT;
     infof(data, "WS: send OPCODE TEXT");
@@ -624,6 +625,11 @@ static size_t ws_packethead(struct Curl_
         firstbyte);
   infof(data, "WS: send payload len %u", (int)len);
 
+  /* 4 bytes random */
+  result = Curl_rand(data, (unsigned char *)&ws->ws.mask, sizeof(ws->ws.mask));
+  if(result)
+    return result;
+
   /* 4 bytes mask */
   memcpy(&out[outi], &ws->ws.mask, 4);
 
