@@ -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