Skip to content

Commit

Permalink
#18 - Validate close status codes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tratcher committed Oct 23, 2014
1 parent b7c8d5c commit 08441ef
Showing 1 changed file with 28 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/Microsoft.AspNet.WebSockets.Protocol/CommonWebSocket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,10 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
Utilities.MaskInPlace(_frameInProgress.MaskKey, new ArraySegment<byte>(_receiveBuffer, _receiveBufferOffset, (int)_frameBytesRemaining));
}
_closeStatus = (WebSocketCloseStatus)((_receiveBuffer[_receiveBufferOffset] << 8) | _receiveBuffer[_receiveBufferOffset + 1]);
if (!ValidateCloseStatus(_closeStatus.Value))
{
await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid close status code.", cancellationToken);
}
try
{
var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
Expand Down Expand Up @@ -451,6 +455,29 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
return result;
}

private static bool ValidateCloseStatus(WebSocketCloseStatus closeStatus)
{
if (closeStatus < (WebSocketCloseStatus)1000 || closeStatus >= (WebSocketCloseStatus)5000)
{
return false;
}
else if (closeStatus >= (WebSocketCloseStatus)3000)
{
// 3000-3999 - Reserved for frameworks
// 4000-4999 - Reserved for private usage
return true;
}
int[] validCodes = new[] { 1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011 };
foreach (var validCode in validCodes)
{
if (closeStatus == (WebSocketCloseStatus)validCode)
{
return true;
}
}
return false;
}

public async override Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
{
ThrowIfDisposed();
Expand Down Expand Up @@ -592,7 +619,7 @@ private void ValidateSegment(ArraySegment<byte> buffer)

private async Task SendErrorAbortAndThrow(WebSocketCloseStatus error, string message, CancellationToken cancellationToken)
{
if (State == WebSocketState.Open)
if (State == WebSocketState.Open || State == WebSocketState.CloseReceived)
{
await CloseOutputAsync(error, message, cancellationToken);
}
Expand Down

0 comments on commit 08441ef

Please sign in to comment.