From 309aa7fe05fea283a508bbb703382ece7ca5316d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 12 Mar 2026 17:30:50 -0700 Subject: [PATCH 1/2] [release/9.0-staging] Deny unmasked frame receive for WebSocket Server (#123661) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of #123485 to release/9.0-staging /cc @liveans Increasing RFC compliance for WebSocket ## Customer Impact RFC compliance ## Regression No ## Testing Manual verification + automated tests ## Risk Low, the change only affects non‑compliant WebSocket clients sending unmasked frames, which is explicitly disallowed by RFC 6455. No behavior change is expected for compliant clients. --------- Co-authored-by: Ahmet İbrahim Aksoy Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/Resources/Strings.resx | 3 +++ .../src/System/Net/WebSockets/ManagedWebSocket.cs | 5 +++++ .../System.Net.WebSockets/tests/WebSocketTests.cs | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx b/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx index a57e81b239a92c..a6033ed9cf8313 100644 --- a/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx +++ b/src/libraries/System.Net.WebSockets/src/Resources/Strings.resx @@ -117,6 +117,9 @@ The WebSocket server sent a masked frame. + + The WebSocket client sent an unmasked frame. + The WebSocket received a continuation frame from a previous final message. diff --git a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs index 8a26a4c29e2eb0..1e80e82bdde01a 100644 --- a/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs +++ b/src/libraries/System.Net.WebSockets/src/System/Net/WebSockets/ManagedWebSocket.cs @@ -1366,6 +1366,11 @@ private async ValueTask CloseWithReceiveErrorAndThrowAsync( // Consume the mask bytes ConsumeFromBuffer(4); } + else if (_isServer) + { + resultHeader = default; + return SR.net_Websockets_ServerReceivedUnmaskedFrame; + } // Do basic validation of the header switch (header.Opcode) diff --git a/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs b/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs index 73e84998a94197..41c7fe341d266d 100644 --- a/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs +++ b/src/libraries/System.Net.WebSockets/tests/WebSocketTests.cs @@ -182,6 +182,20 @@ public async Task ThrowWhenContinuationWithDifferentCompressionFlags() client.SendAsync(Memory.Empty, WebSocketMessageType.Binary, WebSocketMessageFlags.EndOfMessage, default)); } + [Fact] + public async Task ReceiveAsync_ServerUnmaskedFrame_ThrowsWebSocketException() + { + byte[] frame = { 0x81, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F }; + using var stream = new MemoryStream(); + stream.Write(frame, 0, frame.Length); + stream.Position = 0; + using WebSocket websocket = WebSocket.CreateFromStream(stream, new WebSocketCreationOptions { IsServer = true }); + WebSocketException exception = await Assert.ThrowsAsync(() => + websocket.ReceiveAsync(new byte[5], CancellationToken.None)); + Assert.Equal(SR.net_Websockets_ServerReceivedUnmaskedFrame, exception.Message); + Assert.Equal(WebSocketState.Aborted, websocket.State); + } + [Fact] public async Task ReceiveAsync_WhenDisposedInParallel_DoesNotGetStuck() { From 3832bc67ba5a5152411af21ac4de19239147cfa0 Mon Sep 17 00:00:00 2001 From: Steve Pfister Date: Thu, 19 Mar 2026 12:57:55 -0400 Subject: [PATCH 2/2] Remove Homebrew LLVM during macOS CI setup The CI runner image may ship with a Homebrew LLVM whose libraries (e.g., an x86_64-only libunwind.dylib in /usr/local/lib) conflict with the Apple SDK and break native linking. The build uses Apple clang from /usr/bin/clang exclusively and does not need Homebrew LLVM. Backport of https://github.com/dotnet/runtime/pull/125763 --- eng/install-native-dependencies.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/eng/install-native-dependencies.sh b/eng/install-native-dependencies.sh index f8c9db632860de..d09651ca1e1a66 100755 --- a/eng/install-native-dependencies.sh +++ b/eng/install-native-dependencies.sh @@ -44,6 +44,13 @@ case "$os" in export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 # Skip brew update for now, see https://github.com/actions/setup-python/issues/577 # brew update --preinstall + + # Remove Homebrew LLVM if present. The CI runner image may ship with a + # Homebrew LLVM whose libraries (e.g., libunwind.dylib) are the wrong + # architecture or conflict with the Apple SDK, breaking native linking. + # The build uses Apple clang from /usr/bin/clang exclusively. + brew uninstall --ignore-dependencies llvm 2>/dev/null || true + brew bundle --no-upgrade --file "$(dirname "$0")/Brewfile" ;;