Skip to content

Commit 7d11034

Browse files
committed
#14 - Validate reserved bits.
1 parent 207767a commit 7d11034

File tree

2 files changed

+34
-4
lines changed

2 files changed

+34
-4
lines changed

src/Microsoft.AspNet.WebSockets.Protocol/CommonWebSocket.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,12 @@ public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byt
221221
{
222222
if (!_firstDataOpCode.HasValue)
223223
{
224-
throw new InvalidOperationException("A continuation can't be the first frame");
224+
if (State == WebSocketState.Open)
225+
{
226+
await CloseOutputAsync(WebSocketCloseStatus.ProtocolError, "Invalid continuation frame", cancellationToken);
227+
Abort();
228+
}
229+
throw new InvalidOperationException("A continuation can't be the first frame"); // TODO: WebSocketException
225230
}
226231
opCode = _firstDataOpCode.Value;
227232
}
@@ -256,8 +261,12 @@ public async override Task<WebSocketReceiveResult> ReceiveAsync(ArraySegment<byt
256261
if (messageType == WebSocketMessageType.Text
257262
&& !Utilities.TryValidateUtf8(new ArraySegment<byte>(buffer.Array, buffer.Offset, bytesToCopy), _frameInProgress.Fin, _incomingUtf8MessageState))
258263
{
259-
await CloseOutputAsync(WebSocketCloseStatus.InvalidPayloadData, string.Empty, cancellationToken);
260-
throw new InvalidOperationException("An invalid UTF-8 payload was received.");
264+
if (State == WebSocketState.Open)
265+
{
266+
await CloseOutputAsync(WebSocketCloseStatus.InvalidPayloadData, "Invalid UTF-8", cancellationToken);
267+
Abort();
268+
}
269+
throw new InvalidOperationException("An invalid UTF-8 payload was received."); // TODO: WebSocketException
261270
}
262271

263272
if (bytesToCopy == _frameBytesRemaining)
@@ -292,9 +301,24 @@ private async Task ReadNextFrameAsync(CancellationToken cancellationToken)
292301
_receiveBufferBytes -= frameHeaderSize;
293302
_frameBytesRemaining = _frameInProgress.DataLength;
294303

304+
if (_frameInProgress.AreReservedSet())
305+
{
306+
if (State == WebSocketState.Open)
307+
{
308+
await CloseOutputAsync(WebSocketCloseStatus.ProtocolError, "Unexpected reserved bits set", cancellationToken);
309+
Abort();
310+
}
311+
throw new InvalidOperationException("Unexpected reserved bits are set."); // TODO: WebSocketException
312+
}
313+
295314
if (_unmaskInput != _frameInProgress.Masked)
296315
{
297-
throw new InvalidOperationException("Unmasking settings out of sync with data.");
316+
if (State == WebSocketState.Open)
317+
{
318+
await CloseOutputAsync(WebSocketCloseStatus.ProtocolError, "Incorrect masking", cancellationToken);
319+
Abort();
320+
}
321+
throw new InvalidOperationException("Unmasking settings out of sync with data."); // TODO: WebSocketException
298322
}
299323

300324
if (_frameInProgress.OpCode == Constants.OpCodes.PingFrame || _frameInProgress.OpCode == Constants.OpCodes.PongFrame)

src/Microsoft.AspNet.WebSockets.Protocol/FrameHeader.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ public ArraySegment<byte> Buffer
209209
}
210210
}
211211

212+
// bits 1-3.
213+
internal bool AreReservedSet()
214+
{
215+
return (_header[0] & 0x70) != 0;
216+
}
217+
212218
// Given the second bytes of a frame, calculate how long the whole frame header should be.
213219
// Range 2-12 bytes
214220
public static int CalculateFrameHeaderSize(byte b2)

0 commit comments

Comments
 (0)