Skip to content

Commit 08441ef

Browse files
committed
#18 - Validate close status codes.
1 parent b7c8d5c commit 08441ef

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,10 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
414414
Utilities.MaskInPlace(_frameInProgress.MaskKey, new ArraySegment<byte>(_receiveBuffer, _receiveBufferOffset, (int)_frameBytesRemaining));
415415
}
416416
_closeStatus = (WebSocketCloseStatus)((_receiveBuffer[_receiveBufferOffset] << 8) | _receiveBuffer[_receiveBufferOffset + 1]);
417+
if (!ValidateCloseStatus(_closeStatus.Value))
418+
{
419+
await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid close status code.", cancellationToken);
420+
}
417421
try
418422
{
419423
var encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
@@ -451,6 +455,29 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
451455
return result;
452456
}
453457

458+
private static bool ValidateCloseStatus(WebSocketCloseStatus closeStatus)
459+
{
460+
if (closeStatus < (WebSocketCloseStatus)1000 || closeStatus >= (WebSocketCloseStatus)5000)
461+
{
462+
return false;
463+
}
464+
else if (closeStatus >= (WebSocketCloseStatus)3000)
465+
{
466+
// 3000-3999 - Reserved for frameworks
467+
// 4000-4999 - Reserved for private usage
468+
return true;
469+
}
470+
int[] validCodes = new[] { 1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011 };
471+
foreach (var validCode in validCodes)
472+
{
473+
if (closeStatus == (WebSocketCloseStatus)validCode)
474+
{
475+
return true;
476+
}
477+
}
478+
return false;
479+
}
480+
454481
public async override Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
455482
{
456483
ThrowIfDisposed();
@@ -592,7 +619,7 @@ private void ValidateSegment(ArraySegment<byte> buffer)
592619

593620
private async Task SendErrorAbortAndThrow(WebSocketCloseStatus error, string message, CancellationToken cancellationToken)
594621
{
595-
if (State == WebSocketState.Open)
622+
if (State == WebSocketState.Open || State == WebSocketState.CloseReceived)
596623
{
597624
await CloseOutputAsync(error, message, cancellationToken);
598625
}

0 commit comments

Comments
 (0)