@@ -414,6 +414,10 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
414
414
Utilities . MaskInPlace ( _frameInProgress . MaskKey , new ArraySegment < byte > ( _receiveBuffer , _receiveBufferOffset , ( int ) _frameBytesRemaining ) ) ;
415
415
}
416
416
_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
+ }
417
421
try
418
422
{
419
423
var encoding = new UTF8Encoding ( encoderShouldEmitUTF8Identifier : false , throwOnInvalidBytes : true ) ;
@@ -451,6 +455,29 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
451
455
return result ;
452
456
}
453
457
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
+
454
481
public async override Task CloseAsync ( WebSocketCloseStatus closeStatus , string statusDescription , CancellationToken cancellationToken )
455
482
{
456
483
ThrowIfDisposed ( ) ;
@@ -592,7 +619,7 @@ private void ValidateSegment(ArraySegment<byte> buffer)
592
619
593
620
private async Task SendErrorAbortAndThrow ( WebSocketCloseStatus error , string message , CancellationToken cancellationToken )
594
621
{
595
- if ( State == WebSocketState . Open )
622
+ if ( State == WebSocketState . Open || State == WebSocketState . CloseReceived )
596
623
{
597
624
await CloseOutputAsync ( error , message , cancellationToken ) ;
598
625
}
0 commit comments