Skip to content

Commit ae77def

Browse files
committed
#20 - Validate OpCodes.
1 parent 08441ef commit ae77def

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed

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

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Diagnostics.Contracts;
66
using System.IO;
7+
using System.Linq;
78
using System.Net.WebSockets;
89
using System.Text;
910
using System.Threading;
@@ -302,6 +303,11 @@ private async Task ReadNextFrameAsync(CancellationToken cancellationToken)
302303
await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Incorrect masking", cancellationToken);
303304
}
304305

306+
if (!ValidateOpCode(_frameInProgress.OpCode))
307+
{
308+
await SendErrorAbortAndThrow(WebSocketCloseStatus.ProtocolError, "Invalid opcode: " + _frameInProgress.OpCode, cancellationToken);
309+
}
310+
305311
if (_frameInProgress.IsControlFrame)
306312
{
307313
if (_frameBytesRemaining > 125)
@@ -455,29 +461,6 @@ private async Task<WebSocketReceiveResult> ProcessCloseFrameAsync(CancellationTo
455461
return result;
456462
}
457463

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-
481464
public async override Task CloseAsync(WebSocketCloseStatus closeStatus, string statusDescription, CancellationToken cancellationToken)
482465
{
483466
ThrowIfDisposed();
@@ -617,6 +600,34 @@ private void ValidateSegment(ArraySegment<byte> buffer)
617600
}
618601
}
619602

603+
private bool ValidateOpCode(int opCode)
604+
{
605+
return Constants.OpCodes.ValidOpCodes.Contains(opCode);
606+
}
607+
608+
private static bool ValidateCloseStatus(WebSocketCloseStatus closeStatus)
609+
{
610+
if (closeStatus < (WebSocketCloseStatus)1000 || closeStatus >= (WebSocketCloseStatus)5000)
611+
{
612+
return false;
613+
}
614+
else if (closeStatus >= (WebSocketCloseStatus)3000)
615+
{
616+
// 3000-3999 - Reserved for frameworks
617+
// 4000-4999 - Reserved for private usage
618+
return true;
619+
}
620+
int[] validCodes = new[] { 1000, 1001, 1002, 1003, 1007, 1008, 1009, 1010, 1011 };
621+
foreach (var validCode in validCodes)
622+
{
623+
if (closeStatus == (WebSocketCloseStatus)validCode)
624+
{
625+
return true;
626+
}
627+
}
628+
return false;
629+
}
630+
620631
private async Task SendErrorAbortAndThrow(WebSocketCloseStatus error, string message, CancellationToken cancellationToken)
621632
{
622633
if (State == WebSocketState.Open || State == WebSocketState.CloseReceived)

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,17 @@ public static class OpCodes
2525
public const int BinaryFrame = 0x2;
2626
public const int CloseFrame = 0x8;
2727
public const int PingFrame = 0x9;
28-
public const int PongFrame = 0xA;
28+
public const int PongFrame = 0xA;
29+
30+
internal static readonly int[] ValidOpCodes = new int[]
31+
{
32+
ContinuationFrame,
33+
TextFrame,
34+
BinaryFrame,
35+
CloseFrame,
36+
PingFrame,
37+
PongFrame,
38+
};
2939
}
3040
}
3141
}

0 commit comments

Comments
 (0)