Formatted Do not use functions that input characters and convert them to integers if the functions cannot handle all possible inputs. For example, formatted input functions such as scanf()
, fscanf()
, vscanf()
, and vfscanf()
can be used to read string data from stdin
or (in the cases of fscanf()
and vfscanf()
) other input streamstreams. These functions work fine for valid integer values but lack robust error handling for invalid values.
Wiki Markup |
---|
Instead of these functions, try inputing the value as a string and then converting it to an integer value using {{strtol()}} or a related function \[[INT06-A|INT06-A. Use strtol() to convert a string token to an integer]\]. |
...
Alternatively, input character data as a null-terminated byte string and convert to an integer value using strtol()
or a related function. (See ERR34-C. Detect errors when converting a string to a number.)
Noncompliant Code Example
This noncompliant code example uses the scanf()
function to read a string from stdin
and convert it to a long
. The scanf()
and fscanf()
functions have undefined behavior if the value of the result of this operation cannot be represented as an integer.
Code Block | ||||
---|---|---|---|---|
| ||||
long num_long;
if (scanf("%ld", &num_long) != 1) {
/* Handle error */
}
|
In general, do not use scanf()
to parse integers or floating-point numbers from input strings because the input could contain numbers not representable by the argument type.
Compliant Solution (Linux)
This compliant example uses the Linux scanf()
implementation's built-in error handling to validate input. On Linux platforms, scanf()
sets errno
to ERANGE
if the result of integer conversion cannot be represented within the size specified by the format string [Linux 2008]. Note that this solution is platform dependent, so it should be used only where portability is not a concern.
Code Block | ||||
---|---|---|---|---|
| ||||
long num_long;
errno = 0;
if (scanf("%ld", &num_long) != 1) {
/* Handle error */
}
else if (ERANGE == errno) {
if (puts("number out of range\n") == EOF) {
/* Handle error */
}
}
|
Compliant Solution
This compliant example uses fgets()
to input a string and strtol()
to convert the string to an integer. Error checking is provided to make sure the value is a valid integer in the range of long
.
Code Block | ||||
---|---|---|---|---|
| ||||
char buff[25];
char *end_ptr;
long num_long;
if (fgets(buff, sizeof(buff), stdin) == NULL) {
if (puts("EOF or read error\n") == EOF) {
/* Handle error */
}
} else {
errno = 0;
num_long = strtol(buff, &end_ptr, 10);
if (ERANGE == errno) {
if (puts("number out of range\n") == EOF) {
/* Handle error */
}
}
else if (end_ptr == buff) {
if (puts("not valid numeric input\n") == EOF) {
/* Handle error */
}
}
else if ('\n' != *end_ptr && '\0' != *end_ptr) {
if (puts("extra characters on input line\n") == EOF) {
/* Handle error */
}
}
}
|
Note that this solution treats any trailing characters, including whitespace characters, as an error condition.
Risk Assessment
Although it is relatively rare for a violation of this recommendation
...
Risk Assessment
While it is relativley rare for a violation of this rule to result in a security vulnerability, it could more can easily result in loss lost or misinterpreted data.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
INT05- |
1 (low)
2 (low)
2 (medium)
P2
L3
C | Medium | Probable | High | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Axivion Bauhaus Suite |
| CertC-INT05 | |||||||
CodeSonar |
| MISC.NEGCHAR | Negative Character Value | ||||||
Compass/ROSE | Can detect violations of this recommendation. In particular, it notes uses of the | ||||||||
Helix QAC |
| C5005 | |||||||
LDRA tool suite |
| 44 S | Enhanced Enforcement | ||||||
Parasoft C/C++test |
| CERT_C-INT05-a | Avoid using unsafe string functions that do not check bounds | ||||||
PC-lint Plus |
| 586 | Fully supported |
Related Vulnerabilities
Search for Examples of vulnerabilities resulting from the violation of this recommendation can be found on the CERTwebsite.
References
rule on the CERT website.
Related Guidelines
SEI CERT C++ Coding Standard | VOID INT05-CPP. Do not use input functions to convert character data if they cannot handle all possible inputs |
MITRE CWE | CWE-192, Integer coercion error CWE-197, Numeric truncation error |
Bibliography
...
\[[Klein 02|AA. C References#Klein 02]]
\[[ISO/IEC 9899-1999|AA. C References#ISO/IEC 9899-1999]] Section 7.20.1.4, "The strtol, strtoll, strtoul, and strtoull functions," and Section 7.19.6, "Formatted input/output functions" Wiki Markup