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 streams. These functions work fine for valid integer values but lack robust error handling for invalid values.
Alternatively, input character data as a null-terminated byte string and convert to an integer value using strtol()
or a related function (see INT06-C. Use strtol() or a related function to convert a string token to an integer).
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.
long sl; if (scanf("%ld", &sl) != 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
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 that the value is a valid integer in the range of long
.
char buff[25]; char *end_ptr; long sl; if (fgets(buff, sizeof(buff), stdin) == NULL) { if (puts("EOF or read error\n") == EOF) { /* Handle Error */ } } else { errno = 0; sl = 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 white-space characters, as an error condition.
Risk Assessment
While it is relatively rare for a violation of this rule to result in a security vulnerability, it can easily result in loss or misinterpreted data.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
INT05-C |
medium |
probable |
high |
P4 |
L3 |
Automated Detection
Fortify SCA Version 5.0 with the CERT C Rule Pack can detect violations of this recommendation.
Compass/ROSE can detect violations of this recommendation. In particular, it notes uses of the scanf()
family of functions where on the type specifier is a floating point or integer type.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[Klein 02]]
[[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"
[[MITRE 07]] CWE ID 192, "Integer Coercion Error"; CWE ID 197, "Numeric Truncation Error"
INT04-C. Enforce limits on integer values originating from untrusted sources 04. Integers (INT) INT06-C. Use strtol() or a related function to convert a string token to an integer