CWE-126, Buffer Over-read, is a specific form of CWE-125. The product reads from a buffer using indexes or pointers that reference memory locations after the targeted buffer. The read just keeps going past the end.
MITRE lists C and C++, memory-unsafe languages, as the platforms. Any code that scans strings, walks arrays or processes length-prefixed messages can fall into it.
How it happens
Two patterns account for most over-reads.
A missing terminator. C strings end with a NUL byte. If a buffer is filled with data that has no terminator, functions like strlen and strcpy keep reading until they find a zero somewhere in memory. MITRE's observed example CVE-2009-2523 is this pattern: the product does not handle an input string that is not NULL terminated, leading to an over-read or a heap-based overflow.
A length that is not what it claims. CVE-2014-0160, Heartbleed, is described by MITRE as a chain where an inconsistent length parameter enabled an out-of-bounds read that returned memory which could include private cryptographic keys and other sensitive data.
A third example in the record is CVE-2022-1733, a text editor reading past the end of a line while indenting C code.
// Vulnerable: buf may not be NUL terminated
char buf[8];
read(fd, buf, sizeof buf); // fills all 8 bytes, no terminator
printf("name: %s\n", buf); // keeps reading past buf
// Fixed: leave room for the terminator and add it
char buf[9];
ssize_t n = read(fd, buf, sizeof buf - 1);
if (n < 0) return -1;
buf[n] = '\0';
printf("name: %s\n", buf);
What an attacker gains
MITRE lists three consequences.
- Reading memory. The attacker can get secret values or memory addresses.
- Bypassing protection mechanisms. Addresses learned through an over-read can defeat protections such as ASLR, which improves the reliability of exploiting a separate bug to get code execution.
- Crashes and other effects. The product may read a memory location it is not allowed to, causing a segmentation fault, or the read may return more data than intended.
How to find it
- Static analysis. SAST can find some instances by analyzing source code or compiled code without running it.
- Runtime checks. AddressSanitizer inserts checks for memory safety errors during compilation. An over-read then aborts with a report. MITRE notes that crafted inputs are still needed to reach the code with the error, so combine ASan with fuzzing or unit tests that supply unterminated and over-long data.
How to fix it
The record lists no mitigations, so these steps come from the causes.
- Use length-aware functions, for example
strnlen,memchrwith a size, andsnprintf. - Add the terminator yourself after reads that fill a buffer, and size the buffer to leave room for it.
- Compare any length that arrives in a message to the amount of data you actually have.
- Treat externally supplied data as bytes with a length, not as a C string.
- Test with inputs that have no terminator, a lying length field and a zero length.
Quick check
How is a buffer over-read different from an overflow?
An over-read reads memory past the buffer end and mainly exposes data. An overflow writes past the end and corrupts memory.
What is a quick way to trigger an over-read in testing?
Give a parser data with no NUL terminator or a length field larger than the real data, and run it under AddressSanitizer.