Base · Medium

CWE-786: Access of Memory Location Before Start of Buffer

The product reads or writes to a buffer using an index or pointer that references a memory location prior to the beginning of the buffer.

CWE-786 · Base Level ·7 CVEs

Description

The product reads or writes to a buffer using an index or pointer that references a memory location prior to the beginning of the buffer.

This typically occurs when a pointer or its index is decremented to a position before the buffer, when pointer arithmetic results in a position before the beginning of the valid memory location, or when a negative index is used.

Potential Impact

Confidentiality

Read Memory

Integrity, Availability

Modify Memory, DoS: Crash, Exit, or Restart

Integrity

Modify Memory, Execute Unauthorized Code or Commands

Demonstrative Examples

In the following C/C++ example, a utility function is used to trim trailing whitespace from a character string. The function copies the input string to a local character string and uses a while statement to remove the trailing whitespace by moving backward through the string and overwriting whitespace with a NUL character.
Bad
char* trimTrailingWhitespace(char *strMessage, int length) {
                        char *retMessage;char *message = malloc(sizeof(char)*(length+1));
                           
                           // copy input string to a temporary string
                           char message[length+1];int index;for (index = 0; index < length; index++) {message[index] = strMessage[index];}message[index] = '\0';
                           
                           // trim trailing whitespace
                           int len = index-1;while (isspace(message[len])) {message[len] = '\0';len--;}
                           
                           // return string without trailing whitespace
                           retMessage = message;return retMessage;
                     }
However, this function can cause a buffer underwrite if the input character string contains all whitespace. On some systems the while statement will move backwards past the beginning of a character string and will call the isspace() function on an address outside of the bounds of the local buffer.
The following example asks a user for an offset into an array to select an item.
Bad
int main (int argc, char **argv) {char *items[] = {"boat", "car", "truck", "train"};int index = GetUntrustedOffset();printf("You selected %s\n", items[index-1]);}
The programmer allows the user to specify which element in the list to select, however an attacker can provide an out-of-bounds offset, resulting in a buffer over-read (CWE-126).
The following is an example of code that may result in a buffer underwrite. This code is attempting to replace the substring "Replace Me" in destBuf with the string stored in srcBuf. It does so by using the function strstr(), which returns a pointer to the found substring in destBuf. Using pointer arithmetic, the starting index of the substring is found.
Bad
int main() {
                     ...
                     char *result = strstr(destBuf, "Replace Me");
                     int idx = result - destBuf;
                     strcpy(&destBuf[idx], srcBuf);
                     ...}
In the case where the substring is not found in destBuf, strstr() will return NULL, causing the pointer arithmetic to be undefined, potentially setting the value of idx to a negative number. If idx is negative, this will result in a buffer underwrite of destBuf.

Detection Methods

  • Fuzzing High — Fuzz testing (fuzzing) is a powerful technique for generating large numbers of diverse inputs - either randomly or algorithmically - and dynamically invoking the code with those inputs. Even with random inputs, it is often capable of generating unexpected results such as crashes, memory corruption,
  • Automated Dynamic Analysis Moderate — Use tools that are integrated during compilation to insert runtime error-checking mechanisms related to memory safety errors, such as AddressSanitizer (ASan) for C/C++ [REF-1518].

Real-World CVE Examples

CVE IDDescription
CVE-2002-2227Unchecked length of SSLv2 challenge value leads to buffer underflow.
CVE-2007-4580Buffer underflow from a small size value with a large buffer (length parameter inconsistency, CWE-130)
CVE-2007-1584Buffer underflow from an all-whitespace string, which causes a counter to be decremented before the buffer while looking for a non-whitespace character.
CVE-2007-0886Buffer underflow resultant from encoded data that triggers an integer overflow.
CVE-2006-6171Product sets an incorrect buffer size limit, leading to "off-by-two" buffer underflow.
CVE-2006-4024Negative value is used in a memcpy() operation, leading to buffer underflow.
CVE-2004-2620Buffer underflow due to mishandled special characters

Taxonomy Mappings

  • CERT C Secure Coding: ARR30-C — Do not form or use out-of-bounds pointers or array subscripts

Frequently Asked Questions

What is CWE-786?

CWE-786 (Access of Memory Location Before Start of Buffer) is a software weakness identified by MITRE's Common Weakness Enumeration. It is classified as a Base-level weakness. The product reads or writes to a buffer using an index or pointer that references a memory location prior to the beginning of the buffer.

How can CWE-786 be exploited?

Attackers can exploit CWE-786 (Access of Memory Location Before Start of Buffer) to read memory. This weakness is typically introduced during the Implementation phase of software development.

How do I prevent CWE-786?

Follow secure coding practices, conduct code reviews, and use automated security testing tools (SAST/DAST) to detect this weakness early in the development lifecycle.

What is the severity of CWE-786?

CWE-786 is classified as a Base-level weakness (Medium abstraction). It has been observed in 7 real-world CVEs.