CWE-170: Improper Null Termination

Description:
The product does not terminate or incorrectly terminates a string or array with a null character or equivalent terminator.

Extended Description:
Null termination errors frequently occur in two different ways. An off-by-one error could cause a null to be written out of bounds, leading to an overflow. Or, a program could use a strncpy() function call incorrectly, which prevents a null terminator from being added at all. Other scenarios are possible.

Affected languages: C, C++
Parent weaknesses: CWE-707, CWE-20

Consequences:
  - Confidentiality: Read Memory
  - Confidentiality: DoS: Crash, Exit, or Restart
  - Integrity: Modify Memory
  - Integrity: Alter Execution Logic

Detection methods:
  - Automated Static Analysis: 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 havin

Mitigations:
  - [Requirements] Use a language that is not susceptible to these issues. However, be careful of null byte interaction errors (CWE-626) with lower-level constructs that may be written in a language that is susceptible.
  - [Implementation] Ensure that all string functions used are understood fully as to how they append null characters. Also, be wary of off-by-one errors when appending nulls to the end of strings.
  - [Implementation] If performance constraints permit, special code can be added that validates null-termination of string buffers, this is a rather naive and error-prone solution.
  - [Implementation] Switch to bounded string manipulation functions. Inspect buffer lengths involved in the buffer overrun trace reported with the defect.

Demonstrative examples:
The following code reads from cfgfile and copies the input into inputbuf using strcpy(). The code mistakenly assumes that inputbuf will always contain a NULL terminator.
The code above will behave correctly if the data read from cfgfile is null terminated on disk as expected. But if an attacker is able to modify this input so that it does not contain the expected NULL character, the call to strcpy() will continue copying from memory until it encounters an arbitrary NULL character. This will likely overflow the destination buffer and, if the attacker can control the contents of memory immediately following inputbuf, can leave the application susceptible to a buffer overflow attack.
#define MAXLEN 1024 ... char *pathbuf[MAXLEN]; ... read(cfgfile,inputbuf,MAXLEN); //does not null terminate st

In the following code, readlink() expands the name of a symbolic link stored in pathname and puts the absolute path into buf. The length of the resulting value is then calculated using strlen().
The code above will not always behave correctly as readlink() does not append a NULL byte to buf. Readlink() will stop copying characters once the maximum size of buf has been reached to avoid overflowing the buffer, this will leave the value buf not NULL terminated. In this situation, strlen() will continue traversing memory until it encounters an arbitrary NULL character further on down the stack, resulting in a length value that is much larger than the size of string. Readlink() does return the number of bytes copied, but when this return value is the same as stated buf size (in this case MAXPAT

Real-world examples:
  - CVE-2000-0312: Attacker does not null-terminate argv[] when invoking another program.
  - CVE-2003-0777: Interrupted step causes resultant lack of null termination.
  - CVE-2004-1072: Fault causes resultant lack of null termination, leading to buffer expansion.
  - CVE-2001-1389: Multiple vulnerabilities related to improper null termination.
  - CVE-2003-0143: Product does not null terminate a message buffer after snprintf-like call, leading to overflow.