CWE

Common Weakness Enumeration

A Community-Developed List of Software Weakness Types

CWE Top 25 Most Dangerous Software Errors
Home > CWE List > CWE- Individual Dictionary Definition (3.4)  
ID

CWE-787: Out-of-bounds Write

Weakness ID: 787
Abstraction: Base
Structure: Simple
Status: Draft
Presentation Filter:
+ Description
The software writes data past the end, or before the beginning, of the intended buffer.
+ Extended Description
Typically, this can result in corruption of data, a crash, or code execution. The software may modify an index or perform pointer arithmetic that references a memory location that is outside of the boundaries of the buffer. A subsequent write operation then produces undefined or unexpected results.
+ Relationships

The table(s) below shows the weaknesses and high level categories that are related to this weakness. These relationships are defined as ChildOf, ParentOf, MemberOf and give insight to similar items that may exist at higher and lower levels of abstraction. In addition, relationships such as PeerOf and CanAlsoBe are defined to show similar weaknesses that the user may want to explore.

+ Relevant to the view "Research Concepts" (CWE-1000)
NatureTypeIDName
ChildOfClassClass - a weakness that is described in a very abstract fashion, typically independent of any specific language or technology. More general than a Base weakness.119Improper Restriction of Operations within the Bounds of a Memory Buffer
ParentOfVariantVariant - a weakness that is described at a very low level of detail, typically limited to a specific language or technology. More specific than a Base weakness.121Stack-based Buffer Overflow
ParentOfVariantVariant - a weakness that is described at a very low level of detail, typically limited to a specific language or technology. More specific than a Base weakness.122Heap-based Buffer Overflow
ParentOfBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.123Write-what-where Condition
ParentOfBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.124Buffer Underwrite ('Buffer Underflow')
CanFollowBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.822Untrusted Pointer Dereference
CanFollowBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.823Use of Out-of-range Pointer Offset
CanFollowBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.824Access of Uninitialized Pointer
CanFollowBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.825Expired Pointer Dereference
+ Relevant to the view "Weaknesses for Simplified Mapping of Published Vulnerabilities" (CWE-1003)
NatureTypeIDName
ChildOfClassClass - a weakness that is described in a very abstract fashion, typically independent of any specific language or technology. More general than a Base weakness.119Improper Restriction of Operations within the Bounds of a Memory Buffer
+ Relevant to the view "Development Concepts" (CWE-699)
NatureTypeIDName
ChildOfClassClass - a weakness that is described in a very abstract fashion, typically independent of any specific language or technology. More general than a Base weakness.119Improper Restriction of Operations within the Bounds of a Memory Buffer
ParentOfVariantVariant - a weakness that is described at a very low level of detail, typically limited to a specific language or technology. More specific than a Base weakness.121Stack-based Buffer Overflow
ParentOfVariantVariant - a weakness that is described at a very low level of detail, typically limited to a specific language or technology. More specific than a Base weakness.122Heap-based Buffer Overflow
ParentOfBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.123Write-what-where Condition
ParentOfBaseBase - a weakness that is described in an abstract fashion, but with sufficient details to infer specific methods for detection and prevention. More general than a Variant weakness, but more specific than a Class weakness.124Buffer Underwrite ('Buffer Underflow')
+ Modes Of Introduction

The different Modes of Introduction provide information about how and when this weakness may be introduced. The Phase identifies a point in the software life cycle at which introduction may occur, while the Note provides a typical scenario related to introduction during the given phase.

PhaseNote
Implementation
+ Applicable Platforms
The listings below show possible areas for which the given weakness could appear. These may be for specific named Languages, Operating Systems, Architectures, Paradigms, Technologies, or a class of such platforms. The platform is listed along with how frequently the given weakness appears for that instance.

Languages

C (Often Prevalent)

C++ (Often Prevalent)

Class: Assembly (Undetermined Prevalence)

+ Common Consequences

The table below specifies different individual consequences associated with the weakness. The Scope identifies the application security area that is violated, while the Impact describes the negative technical impact that arises if an adversary succeeds in exploiting this weakness. The Likelihood provides information about how likely the specific consequence is expected to be seen relative to the other consequences in the list. For example, there may be high likelihood that a weakness will be exploited to achieve a certain impact, but a low likelihood that it will be exploited to achieve a different impact.

ScopeImpactLikelihood
Integrity
Availability

Technical Impact: Modify Memory; DoS: Crash, Exit, or Restart; Execute Unauthorized Code or Commands

+ Likelihood Of Exploit
High
+ Demonstrative Examples

Example 1

The following code attempts to save four different identification numbers into an array.

(bad code)
Example Language:
int id_sequence[3];

/* Populate the id array. */

id_sequence[0] = 123;
id_sequence[1] = 234;
id_sequence[2] = 345;
id_sequence[3] = 456;

Example 2

In the following example, it is possible to request that memcpy move a much larger segment of memory than assumed:

(bad code)
Example Language:
int returnChunkSize(void *) {

/* if chunk info is valid, return the size of usable memory,

* else, return -1 to indicate an error

*/
...
}
int main() {
...
memcpy(destBuf, srcBuf, (returnChunkSize(destBuf)-1));
...
}

If returnChunkSize() happens to encounter an error it will return -1. Notice that the return value is not checked before the memcpy operation (CWE-252), so -1 can be passed as the size argument to memcpy() (CWE-805). Because memcpy() assumes that the value is unsigned, it will be interpreted as MAXINT-1 (CWE-195), and therefore will copy far more memory than is likely available to the destination buffer (CWE-787, CWE-788).

Example 3

This example takes an IP address from a user, verifies that it is well formed and then looks up the hostname and copies it into a buffer.

(bad code)
Example Language:
void host_lookup(char *user_supplied_addr){
struct hostent *hp;
in_addr_t *addr;
char hostname[64];
in_addr_t inet_addr(const char *cp);

/*routine that ensures user_supplied_addr is in the right format for conversion */

validate_addr_form(user_supplied_addr);
addr = inet_addr(user_supplied_addr);
hp = gethostbyaddr( addr, sizeof(struct in_addr), AF_INET);
strcpy(hostname, hp->h_name);
}

This function allocates a buffer of 64 bytes to store the hostname, however there is no guarantee that the hostname will not be larger than 64 bytes. If an attacker specifies an address which resolves to a very large hostname, then we may overwrite sensitive data or even relinquish control flow to the attacker.

Note that this example also contains an unchecked return value (CWE-252) that can lead to a NULL pointer dereference (CWE-476).

Example 4

This example applies an encoding procedure to an input string and stores it into a buffer.

(bad code)
Example Language:
char * copy_input(char *user_supplied_string){
int i, dst_index;
char *dst_buf = (char*)malloc(4*sizeof(char) * MAX_SIZE);
if ( MAX_SIZE <= strlen(user_supplied_string) ){
die("user string too long, die evil hacker!");
}
dst_index = 0;
for ( i = 0; i < strlen(user_supplied_string); i++ ){
if( '&' == user_supplied_string[i] ){
dst_buf[dst_index++] = '&';
dst_buf[dst_index++] = 'a';
dst_buf[dst_index++] = 'm';
dst_buf[dst_index++] = 'p';
dst_buf[dst_index++] = ';';
}
else if ('<' == user_supplied_string[i] ){

/* encode to &lt; */
}
else dst_buf[dst_index++] = user_supplied_string[i];
}
return dst_buf;
}

The programmer attempts to encode the ampersand character in the user-controlled string, however the length of the string is validated before the encoding procedure is applied. Furthermore, the programmer assumes encoding expansion will only expand a given character by a factor of 4, while the encoding of the ampersand expands by 5. As a result, when the encoding procedure expands the string it is possible to overflow the destination buffer if the attacker provides a string of many ampersands.

Example 5

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 code)
Example Language:
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.

Example 6

The following is an example of code that may result in a buffer underwrite, if find() returns a negative value to indicate that ch is not found in srcBuf:

(bad code)
Example Language:
int main() {
...
strncpy(destBuf, &srcBuf[find(srcBuf, ch)], 1024);
...
}

If the index to srcBuf is somehow under user control, this is an arbitrary write-what-where condition.

+ Observed Examples
ReferenceDescription
Unchecked length of SSLv2 challenge value leads to buffer underflow.
Buffer underflow from a small size value with a large buffer (length parameter inconsistency, CWE-130)
Chain: integer signedness error (CWE-195) passes signed comparison, leading to heap overflow (CWE-122)
Classic stack-based buffer overflow in media player using a long entry in a playlist
Heap-based buffer overflow in media player using a long entry in a playlist
+ Potential Mitigations

Phase: Requirements

Strategy: Language Selection

Use a language that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.

For example, many languages that perform their own memory management, such as Java and Perl, are not subject to buffer overflows. Other languages, such as Ada and C#, typically provide overflow protection, but the protection can be disabled by the programmer.

Be wary that a language's interface to native code may still be subject to overflows, even if the language itself is theoretically safe.

Phase: Architecture and Design

Strategy: Libraries or Frameworks

Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid.

Examples include the Safe C String Library (SafeStr) by Messier and Viega [REF-57], and the Strsafe.h library from Microsoft [REF-56]. These libraries provide safer versions of overflow-prone string-handling functions.

Note: This is not a complete solution, since many buffer overflows are not related to strings.

Phase: Build and Compilation

Strategy: Compilation or Build Hardening

Run or compile the software using features or extensions that automatically provide a protection mechanism that mitigates or eliminates buffer overflows.

For example, certain compilers and extensions provide automatic buffer overflow detection mechanisms that are built into the compiled code. Examples include the Microsoft Visual Studio /GS flag, Fedora/Red Hat FORTIFY_SOURCE GCC flag, StackGuard, and ProPolice.

Effectiveness: Defense in Depth

Note: This is not necessarily a complete solution, since these mechanisms can only detect certain types of overflows. In addition, an attack could still cause a denial of service, since the typical response is to exit the application.

Phase: Implementation

Consider adhering to the following rules when allocating and managing an application's memory:

  • Double check that your buffer is as large as you specify.
  • When using functions that accept a number of bytes to copy, such as strncpy(), be aware that if the destination buffer size is equal to the source buffer size, it may not NULL-terminate the string.
  • Check buffer boundaries if accessing the buffer in a loop and make sure you are not in danger of writing past the allocated space.
  • If necessary, truncate all input strings to a reasonable length before passing them to the copy and concatenation functions.

Phase: Operation

Strategy: Environment Hardening

Run or compile the software using features or extensions that randomly arrange the positions of a program's executable and libraries in memory. Because this makes the addresses unpredictable, it can prevent an attacker from reliably jumping to exploitable code.

Examples include Address Space Layout Randomization (ASLR) [REF-58] [REF-60] and Position-Independent Executables (PIE) [REF-64].

Effectiveness: Defense in Depth

Note: This is not a complete solution. However, it forces the attacker to guess an unknown value that changes every program execution. In addition, an attack could still cause a denial of service, since the typical response is to exit the application.

Phase: Operation

Strategy: Environment Hardening

Use a CPU and operating system that offers Data Execution Protection (NX) or its equivalent [REF-60] [REF-61].

Effectiveness: Defense in Depth

Note: This is not a complete solution, since buffer overflows could be used to overwrite nearby variables to modify the software's state in dangerous ways. In addition, it cannot be used in cases in which self-modifying code is required. Finally, an attack could still cause a denial of service, since the typical response is to exit the application.

Phase: Implementation

Replace unbounded copy functions with analogous functions that support length arguments, such as strcpy with strncpy. Create these if they are not available.

Effectiveness: Moderate

Note: This approach is still susceptible to calculation errors, including issues such as off-by-one errors (CWE-193) and incorrectly calculating buffer lengths (CWE-131).
+ Detection Methods

Automated Static Analysis

This weakness can often be detected using automated static analysis tools. Many modern tools use data flow analysis or constraint-based techniques to minimize the number of false positives.

Automated static analysis generally does not account for environmental considerations when reporting out-of-bounds memory operations. This can make it difficult for users to determine which warnings should be investigated first. For example, an analysis tool might report buffer overflows that originate from command line arguments in a program that is not expected to run with setuid or other special privileges.

Effectiveness: High

Note: Detection techniques for buffer-related errors are more mature than for most other weakness types.

Automated Dynamic Analysis

This weakness can be detected using dynamic tools and techniques that interact with the software using large test suites with many diverse inputs, such as fuzz testing (fuzzing), robustness testing, and fault injection. The software's operation may slow down, but it should not become unstable, crash, or generate incorrect results.
+ Memberships
This MemberOf Relationships table shows additional CWE Categories and Views that reference this weakness as a member. This information is often useful in understanding where a weakness fits within the context of external information sources.
NatureTypeIDName
MemberOfViewView - a subset of CWE entries that provides a way of examining CWE content. The two main view structures are Slices (flat lists) and Graphs (containing relationships between entries).1200Weaknesses in the 2019 CWE Top 25 Most Dangerous Software Errors
+ References
[REF-1029] Aleph One. "Smashing The Stack For Fun And Profit". 1996-11-08. <http://phrack.org/issues/49/14.html>.
[REF-7] Michael Howard and David LeBlanc. "Writing Secure Code". Chapter 5, "Stack Overruns" Page 129. 2nd Edition. Microsoft Press. 2002-12-04. <https://www.microsoftpressstore.com/store/writing-secure-code-9780735617223>.
[REF-7] Michael Howard and David LeBlanc. "Writing Secure Code". Chapter 5, "Heap Overruns" Page 138. 2nd Edition. Microsoft Press. 2002-12-04. <https://www.microsoftpressstore.com/store/writing-secure-code-9780735617223>.
[REF-44] Michael Howard, David LeBlanc and John Viega. "24 Deadly Sins of Software Security". "Sin 5: Buffer Overruns." Page 89. McGraw-Hill. 2010.
[REF-62] Mark Dowd, John McDonald and Justin Schuh. "The Art of Software Security Assessment". Chapter 3, "Nonexecutable Stack", Page 76. 1st Edition. Addison Wesley. 2006.
[REF-62] Mark Dowd, John McDonald and Justin Schuh. "The Art of Software Security Assessment". Chapter 5, "Protection Mechanisms", Page 189. 1st Edition. Addison Wesley. 2006.
[REF-90] "Buffer UNDERFLOWS: What do you know about it?". Vuln-Dev Mailing List. 2004-01-10. <http://seclists.org/vuln-dev/2004/Jan/0022.html>.
[REF-56] Microsoft. "Using the Strsafe.h Functions". <http://msdn.microsoft.com/en-us/library/ms647466.aspx>.
[REF-57] Matt Messier and John Viega. "Safe C String Library v1.0.3". <http://www.zork.org/safestr/>.
[REF-58] Michael Howard. "Address Space Layout Randomization in Windows Vista". <http://blogs.msdn.com/michael_howard/archive/2006/05/26/address-space-layout-randomization-in-windows-vista.aspx>.
[REF-61] Microsoft. "Understanding DEP as a mitigation technology part 1". <http://blogs.technet.com/b/srd/archive/2009/06/12/understanding-dep-as-a-mitigation-technology-part-1.aspx>.
[REF-64] Grant Murphy. "Position Independent Executables (PIE)". Red Hat. 2012-11-28. <https://securityblog.redhat.com/2012/11/28/position-independent-executables-pie/>.
+ Content History
Submissions
Submission DateSubmitterOrganization
2009-10-21CWE Content TeamMITRE
Modifications
Modification DateModifierOrganization
2010-02-16CWE Content TeamMITRE
updated Demonstrative_Examples
2010-09-27CWE Content TeamMITRE
updated Relationships
2011-06-01CWE Content TeamMITRE
updated Common_Consequences
2014-06-23CWE Content TeamMITRE
updated Demonstrative_Examples
2015-12-07CWE Content TeamMITRE
updated Relationships
2018-03-27CWE Content TeamMITRE
updated Description
2019-09-19CWE Content TeamMITRE
updated Applicable_Platforms, Demonstrative_Examples, Detection_Factors, Likelihood_of_Exploit, Observed_Examples, Potential_Mitigations, References, Relationships, Time_of_Introduction
More information is available — Please select a different filter.
Page Last Updated: September 19, 2019