CWE-704, Incorrect Type Conversion or Cast, is the parent of several type related bugs: the product does not correctly convert an object, resource or structure from one type to another. MITRE lists C, C++, memory-unsafe languages, and not language specific among the platforms.
How it happens
Two observed examples cover both ends of the language spectrum.
CVE-2021-43537 is a chain in a web browser: an unsigned 64 bit integer is forcibly cast to a 32 bit integer, potentially leading to integer overflow and heap memory corruption.
CVE-2022-3979 is a chain in a PHP data visualization program that uses the != operator instead of the type strict !== operator when validating hash values, potentially leading to an incorrect type conversion.
The PHP case is worth a closer look. Loose comparison converts both sides to a common type first, and strings that look like numbers can compare as equal when they are not the same string.
// Vulnerable: loose comparison may convert both values to numbers
if ($expectedHash != $givenHash) { deny(); }
// Fixed: strict comparison, and a constant-time check for secrets
if (!hash_equals($expectedHash, $givenHash)) { deny(); }
What an attacker gains
MITRE leaves the impact open because it depends on where the converted value lands. A truncated size corrupts memory. A loosely compared hash can let a wrong value pass validation.
How to find it
MITRE names fuzzing: generating many diverse inputs and watching for abnormal behavior, which exposes conversion edge cases such as values at the limits of a type. Add compiler warnings for narrowing, and linters that flag loose equality operators.
How to fix it
- Use strict comparison operators in dynamically typed languages.
- Check ranges before narrowing a number, and keep one type for sizes.
- Parse and validate at the boundary, then pass typed values inward.
Quick check
Why use hash_equals over strict equality in PHP?
Strict comparison fixes the type problem, and hash_equals also compares in constant time, which helps with secrets.