For my TCP based network application I am transmitting data using length based message framing. It's quite simple, a packet looks like this:
[Length][Data]
Length is an Int32 telling me the length of the upcoming raw data.
I read the Int and create a byte array
like this:
//Read Int
activePacketLength = (Int32)(bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24));
packetBuffer = new byte[activePacketLength]; //Create buffer
Then I read until I have read x bytes. It works fine, but what if some funny user sends me something like this:
0xFF 0xFF 0xFF 0x7F 0x01 0x02 0x03 ... {and so on}
My code will create a new byte array
with the size of int.MaxValue
(~ 2GB) and will read data until I get a OutOfMemoryException
or so ...
What is a good way to prevent tempering with this? I could implement a size limit (e.g. 1MB per packet, everything higher than that will discard the client and block it) but are there more "standard" solutions which do not feel so hacky?
Since you cannot prevent a client from sending data you consider invalid you must check if the data are invalid. This includes limiting the length of a frame (and thus the value of the length prefix) to the maximum size expected from a non-malicious client. If authentication is part of the protocol it would even be better to have two limits: a small one for non-authenticated clients which should just allow frame sizes needed for authentication and then a larger limit for authenticated clients.