Variant · Low-Medium

CWE-789: Memory Allocation with Excessive Size Value

The product allocates memory based on an untrusted, large size value, but it does not ensure that the size is within expected limits, allowing arbitrary amounts of memory to be allocated.

CWE-789 · Variant Level ·7 CVEs ·2 Mitigations

Description

The product allocates memory based on an untrusted, large size value, but it does not ensure that the size is within expected limits, allowing arbitrary amounts of memory to be allocated.

Potential Impact

Availability

DoS: Resource Consumption (Memory)

Demonstrative Examples

Consider the following code, which accepts an untrusted size value and allocates a buffer to contain a string of the given size.
Bad
unsigned int size = GetUntrustedInt();
                     /* ignore integer overflow (CWE-190) for this example */
                     
                     unsigned int totBytes = size * sizeof(char);char *string = (char *)malloc(totBytes);InitializeString(string);
Suppose an attacker provides a size value of:
This will cause 305,419,896 bytes (over 291 megabytes) to be allocated for the string.
Consider the following code, which accepts an untrusted size value and uses the size as an initial capacity for a HashMap.
Bad
unsigned int size = GetUntrustedInt();HashMap list = new HashMap(size);
The HashMap constructor will verify that the initial capacity is not negative, however there is no check in place to verify that sufficient memory is present. If the attacker provides a large enough value, the application will run into an OutOfMemoryError.
This code performs a stack allocation based on a length calculation.
Bad
int a = 5, b = 6;
		    size_t len = a - b;
		    char buf[len];    // Just blows up the stack
		  
		  }
Since a and b are declared as signed ints, the "a - b" subtraction gives a negative result (-1). However, since len is declared to be unsigned, len is cast to an extremely large positive number (on 32-bit systems - 4294967295). As a result, the buffer buf[len] declaration uses an extremely large size to allocate on the stack, very likely more than the entire computer's memory space.
Miscalculations usually will not be so obvious. The calculation will either be complicated or the result of an attacker's input to attain the negative value.
This example shows a typical attempt to parse a string with an error resulting from a difference in assumptions between the caller to a function and the function's action.
Bad
int proc_msg(char *s, int msg_len)
		 {
                  
		    // Note space at the end of the string - assume all strings have preamble with space
		    int pre_len = sizeof("preamble: ");
		    char buf[pre_len - msg_len];
		    ... Do processing here if we get this far
		  
		  }
		  char *s = "preamble: message\n";
		  char *sl = strchr(s, ':');        // Number of characters up to ':' (not including space)
		  int jnklen = sl == NULL ? 0 : sl - s;    // If undefined pointer, use zero length
		  int ret_val = proc_msg ("s",  jnklen);    // Violate assumption of preamble length, end up with negative value, blow out stack
The buffer length ends up being -1, resulting in a blown out stack. The space character after the colon is included in the function calculation, but not in the caller's calculation. This, unfortunately, is not usually so obvious but exists in an obtuse series of calculations.

Mitigations & Prevention

ImplementationArchitecture and Design

Perform adequate input validation against any value that influences the amount of memory that is allocated. Define an appropriate strategy for handling requests that exceed the limit, and consider supporting a configuration option so that the administrator can extend the amount of memory to be used if necessary.

Operation

Run your program using system-provided resource limits for memory. This might still cause the program to crash or exit, but the impact to the rest of the system will be minimized.

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 Static Analysis High — Automated static analysis, commonly referred to as Static Application Security Testing (SAST), can find some instances of this weakness by analyzing source code (or binary/compiled code) without having to execute it. Typically, this is done by building a model of data flow and control flow, then sea
  • 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-2023-2253Query capability for API endpoint allows a large value for number of records to return, leading to allocation of a large array
CVE-2019-19911Chain: Python library does not limit the resources used to process images that specify a very large number of bands (CWE-1284), leading to excessive memory consumption (CWE-789) or an integer overflow
CVE-2010-3701program uses ::alloca() for encoding messages, but large messages trigger segfault
CVE-2008-1708memory consumption and daemon exit by specifying a large value in a length field
CVE-2008-0977large value in a length field leads to memory consumption and crash when no more memory is available
CVE-2006-3791large key size in game program triggers crash when a resizing function cannot allocate enough memory
CVE-2004-2589large Content-Length HTTP header value triggers application crash in instant messaging application due to failure in memory allocation

Taxonomy Mappings

  • WASC: 35 — SOAP Array Abuse
  • CERT C Secure Coding: MEM35-C — Allocate sufficient memory for an object
  • SEI CERT Perl Coding Standard: IDS32-PL — Validate any integer that is used as an array index
  • OMG ASCSM: ASCSM-CWE-789 —

Frequently Asked Questions

What is CWE-789?

CWE-789 (Memory Allocation with Excessive Size Value) is a software weakness identified by MITRE's Common Weakness Enumeration. It is classified as a Variant-level weakness. The product allocates memory based on an untrusted, large size value, but it does not ensure that the size is within expected limits, allowing arbitrary amounts of memory to be allocated.

How can CWE-789 be exploited?

Attackers can exploit CWE-789 (Memory Allocation with Excessive Size Value) to dos: resource consumption (memory). This weakness is typically introduced during the Implementation phase of software development.

How do I prevent CWE-789?

Key mitigations include: Perform adequate input validation against any value that influences the amount of memory that is allocated. Define an appropriate strategy for handling requests that exceed the limit, and consider sup

What is the severity of CWE-789?

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