The software 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.
Time of Introduction
Implementation
Applicable Platforms
Languages
C
C++
Platform Notes
Conceptually, this does not just apply to the C language; any language or
representation that involves a terminator could have this type of
problem.
Common Consequences
Scope
Effect
Confidentiality
Integrity
The case of an omitted null character is the most dangerous of the
possible issues. This will almost certainly result in information
disclosure, and possibly a buffer overflow condition, which may be
exploited to execute arbitrary code.
Confidentiality
Integrity
Availability
If a null character is omitted from a string, then most string-copying
functions will read data until they locate a null character, even
outside of the intended boundaries of the string. This could:
cause a crash due to a segmentation fault
cause sensitive adjacent memory to be copied and sent to an
outsider
trigger a buffer overflow when the copy is bering written to a
fixed-size buffer
Integrity
Availability
Misplaced null characters may result in any number of security
problems. The biggest issue is a subset of buffer overflow, and
write-what-where conditions, where data corruption occurs from the
writing of a null character over valid data, or even instructions. A
randomly placed null character may put the system into an undefined
state, and therefore make it prone to crashing. A misplaced null
character may corrupt other data in memory
Access Control
Should the null character corrupt the process flow, or affect a flag
controlling access, it may lead to logical errors which allow for the
execution of arbitrary code.
Likelihood of Exploit
Medium
Demonstrative Examples
Example 1
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.
(Bad Code)
C
#define MAXLEN 1024
...
char *pathbuf[MAXLEN];
...
read(cfgfile,inputbuf,MAXLEN); //does not null terminate
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.
Example 2
In the following code, readlink() expands the name of a symbolic
link stored in the buffer path so that the buffer filename contains the
absolute path of the file referenced by the symbolic link. The length of the
resulting value is then calculated using strlen().
(Bad Code)
C
char buf[MAXPATH];
...
readlink(path, buf, MAXPATH);
int length = strlen(filename);
...
The code above will not behave correctly because the value read into
buf by readlink() will not be null terminated. In testing,
vulnerabilities like this one might not be caught because the unused
contents of buf and the memory immediately following it may be NULL,
thereby causing strlen() to appear as if it is behaving correctly.
However, in the wild strlen() will continue traversing memory until it
encounters an arbitrary NULL character on the stack, which results in a
value of length that is much larger than the size of buf and may cause a
buffer overflow in subsequent uses of this value. Buffer overflows
aside, whenever a single call to readlink() returns the same value that
has been passed to its third argument, it is impossible to know whether
the name is precisely that many bytes long, or whether readlink() has
truncated the name to avoid overrunning the buffer. Traditionally,
strings are represented as a region of memory containing data terminated
with a NULL character. Older string-handling methods frequently rely on
this NULL character to determine the length of the string. If a buffer
that does not contain a NULL terminator is passed to one of these
functions, the function will read past the end of the buffer. Malicious
users typically exploit this type of vulnerability by injecting data
with unexpected size or content into the application. They may provide
the malicious input either directly as input to the program or
indirectly by modifying application resources, such as configuration
files. In the event that an attacker causes the application to read
beyond the bounds of a buffer, the attacker may be able use a resulting
buffer overflow to inject and execute arbitrary code on the system.
Example 3
While the following example is not exploitable, it provides a good
example of how nulls can be omitted or misplaced, even when "safe" functions
are used:
(Bad Code)
C
#include <stdio.h>
#include <string.h>
int main() {
char longString[] = "String signifying nothing";
char shortString[16];
strncpy(shortString, longString, 16);
printf("The last character in shortString is: %c %1$x\n",
shortString[15]);
return (0);
}
The above code gives the following output: The last character in
shortString is: l 6c So, the shortString array does not end in a NULL
character, even though the "safe" string function strncpy() was
used.
Product does not null terminate a message buffer
after snprintf-like call, leading to
overflow.
Potential Mitigations
Phase
Description
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.
Implementation
Add code that fills buffers with nulls (however, the length of buffers
still needs to be inspected, to ensure that the non null-terminated
string is not written at the physical end of the buffer).
Weakness Ordinalities
Ordinality
Description
Resultant
(where the
weakness is typically related to the presence of some other
weaknesses)
Factors: this is usually resultant from other weaknesses such as
off-by-one errors, but it can be primary to boundary condition violations
such as buffer overflows. In buffer overflows, it can act as an expander for
assumed-immutable data.
Overlaps missing input terminator.
Causal Nature
Explicit
Taxonomy Mappings
Mapped Taxonomy Name
Node ID
Fit
Mapped Node Name
PLOVER
Improper Null Termination
7 Pernicious Kingdoms
String Termination Error
CLASP
Miscalculated null termination
OWASP Top Ten 2004
A9
CWE More Specific
Denial of Service
CERT C Secure Coding
POS30-C
Use the readlink() function properly
CERT C Secure Coding
STR03-C
Do not inadvertently truncate a null-terminated byte
string
CERT C Secure Coding
STR32-C
Null-terminate byte strings as required
White Box Definitions
A weakness where the code path has:
1. end statement that passes a data item to a null-terminated string
function
2. start statement that produces the improper null-terminated data
item
Where "produces" is defined through the following scenarios:
1. data item never ended with null-terminator
2. null-terminator is re-written
Maintenance Notes
As currently described, this entry is more like a category than a
weakness.
Content History
Submissions
Submission Date
Submitter
Organization
Source
PLOVER
Externally Mined
Modifications
Modification Date
Modifier
Organization
Source
2008-07-01
Eric Dalci
Cigital
External
updated Time of Introduction
2008-08-01
KDM Analytics
External
added/updated white box definitions
2008-09-08
CWE Content Team
MITRE
Internal
updated Applicable Platforms, Causal Nature,
Common Consequences, Description, Likelihood of Exploit, Maintenance Notes,
Relationships, Other Notes, Relationship Notes, Taxonomy Mappings,
Weakness Ordinalities
2008-11-24
CWE Content Team
MITRE
Internal
updated Relationships,
Taxonomy Mappings
2009-03-10
CWE Content Team
MITRE
Internal
updated Common Consequences
2009-05-27
CWE Content Team
MITRE
Internal
updated Demonstrative Examples
2009-07-17
KDM Analytics
External
Improved the White Box Definition
2009-07-27
CWE Content Team
MITRE
Internal
updated Common Consequences, Other Notes,
Potential Mitigations, White Box Definitions