I know that many buffer overflow attacks on servers are conducted by sending very large input strings through some HTML form etc.. The go-to mitigation technique for this, is to validate the length of the string and make sure it is not very long. However, I imagine that the string must be loaded into some fixed size buffer in memory to check it for length in the first place. Why can this not cause a buffer overflow?
I code exclusively in high-level languages where buffer overflow's are not an issue, so I apologize for not having a code example for you.
Example; when writing a string to memory which was received over the network: (untrustable data)
- A space of memory is allocated to store the incoming string.
- A string is read from the network in chunks. In many cases the length is not known.
The string is written at the starting position of the earlier allocation. Additional data is appended at that point until the desired delimiter is found. (i.e.
\nin an HTTP request)
If the string is too long, then the data overflows beyond the allocated space, possibly overwriting additional memory allocated for another purpose. This often produces a safe crash; but in specific circumstances such attacks can have dire consequences, especially if the injected string will be interpreted as executable code.
A secure application will allocate a larger buffer as needed. This occurs automatically in a high-level language.
Alternatively you could truncate or reject data beyond the maximum length.
There are also read-only attacks that be performed on insecure programs:
If a buffer is allocated, but the write is incomplete, (i.e. string received is shorter than expected length) then there will be random data leftover in that buffer. If the buffer is later accessible by the attacker, then random memory can be stolen.
Most high-level languages will zero-out allocated buffers, but this is less efficient, so some languages provide an option (or default) to skip the zero-out step.
Integer overflow vulnerabilities could be used to bypass length checks later in the program. If a maliciously edited integer value is used to read memory locations or to set the length limit of a read operation, then random memory can be stolen.
Integer overflow would occur if math is performed before validation. For example,
if(requestedDataLength + someModifier < limit)should be changed to
if(requestedDataLength < limit - someModifier).
Integer overflow can be used for attacks that are unrelated to buffer allocation. Many high-level languages are be affected by integer overflow, but this is less common.
The consequences may vary but at the worst it could result in theft of sensitive access credentials or sensitive data.
In a high-level language, buffer allocation and length handling is automatic, and these vulnerabilities normally cannot arise.