CWE-197: Numeric Truncation Error
Learn about CWE-197 (Numeric Truncation Error), its security impact, exploitation methods, and prevention guidelines.
What is Numeric Truncation Error?
• Overview: Numeric Truncation Error occurs when a larger numeric data type is converted to a smaller one, leading to loss of high-order bits and resulting in an unexpected, often incorrect, value.
• Exploitation Methods:
- Attackers can exploit this vulnerability by manipulating input values to cause unexpected behavior or incorrect calculations.
- Common attack patterns include inducing buffer overflows or altering control flow by exploiting incorrect loop conditions or array indexing.
• Security Impact:
- Direct consequences include data corruption, unexpected program behavior, and potential crashes.
- Potential cascading effects involve further vulnerabilities being exposed due to incorrect program logic.
- Business impact may include system downtime, breach of data integrity, and loss of user trust.
• Prevention Guidelines:
- Specific code-level fixes include validating and sanitizing input data to ensure it falls within expected ranges before conversion.
- Security best practices involve using data types that can accommodate expected value ranges and employing static analysis tools to identify potential truncation issues.
- Recommended tools and frameworks include using compiler warnings and static code analysis tools like Coverity or SonarQube to detect and mitigate such vulnerabilities.
Corgea can automatically detect and fix Numeric Truncation Error in your codebase. Try Corgea free today.
Technical Details
Likelihood of Exploit:
Affected Languages: C, C++, Java, C#
Affected Technologies: Not specified
Vulnerable Code Example
// Vulnerable code demonstrating numeric truncation error
#include <stdio.h>
void processData(double largeNumber) {
// Assume largeNumber can be very large and is provided by external input
float truncatedNumber = largeNumber; // Conversion from double to float
// Potential numeric truncation if largeNumber is too big for float
printf("Processed number: %.2f\n", truncatedNumber);
}
int main() {
double input = 1.0e+40; // Example of a large number that exceeds float capacity
processData(input);
return 0;
}
Explanation
In this example, the processData
function takes a double
as input and converts it to a float
. If the double
value is too large for a float
to represent accurately, this conversion can lead to a numeric truncation error, where the value is incorrectly represented in the smaller data type.
How to fix Numeric Truncation Error?
To fix the numeric truncation error, you need to ensure that the conversion from a larger numeric type to a smaller one does not result in data loss. This can be achieved by:
- Checking the Range: Before performing the conversion, check if the value is within the range of the target type.
- Using Appropriate Data Types: Select data types that can handle the expected range of values without loss.
- Handling Errors Gracefully: If the conversion cannot be performed safely, handle the error appropriately, such as logging a warning or using a fallback mechanism.
Fixed Code Example
// Fixed code with proper range checks and error handling
#include <stdio.h>
#include <float.h> // For FLT_MAX and FLT_MIN
void processData(double largeNumber) {
// Check if largeNumber can be safely converted to float
if (largeNumber > FLT_MAX || largeNumber < -FLT_MAX) {
// Log an error message or handle the situation appropriately
printf("Error: Number too large to be represented as a float.\n");
return;
}
float truncatedNumber = (float)largeNumber; // Safe conversion ensured
printf("Processed number: %.2f\n", truncatedNumber);
}
int main() {
double input = 1.0e+40; // Example of a large number
processData(input);
return 0;
}
Explanation
In the fixed code example, we have added a range check to ensure that largeNumber
is within the representable range of a float
before performing the conversion. We compare the largeNumber
against FLT_MAX
and -FLT_MAX
, which define the maximum and minimum values for a float
. If the number is out of range, we print an error message and exit the function without attempting the conversion, thus preventing the truncation error. This approach ensures that numeric truncation errors are avoided while handling potential errors gracefully.