Weakness reference
CWE-681

Incorrect Conversion between Numeric Types

This weakness occurs when software converts a value from one numeric type to another for example, from a larger integer to a smaller one, or from a…

01Summary

This weakness occurs when software converts a value from one numeric type to another (for example, from a larger integer to a smaller one, or from a floating-point number to an integer) in a way that loses information or changes the value's meaning. The result can be an out-of-range value, a truncated value, or a sign flip that causes the program to behave unexpectedly or make incorrect security decisions.

02How It Happens

Numeric type conversions happen implicitly or explicitly throughout most programs. When a value is converted to a type that cannot represent it fully—such as fitting a large number into a smaller container, converting a negative number to an unsigned type, or rounding a float to an integer—the original value may be silently altered. If the program then uses this converted value in a security-critical context (such as a bounds check, a permission decision, or a memory allocation size), the altered value can bypass intended protections or trigger unintended behavior.

The risk is highest when conversions happen without explicit validation, when the source and destination types have different ranges or signedness, or when the conversion result is not checked before use in a sensitive operation.

03Real-World Impact

Incorrect numeric conversions can lead to buffer overflows (if a negative size is converted to unsigned and used in memory allocation), authentication bypasses (if a user ID is truncated or sign-flipped), integer overflows in calculations, or incorrect access control decisions. In some cases, an attacker can craft input that, after conversion, passes a bounds check that should have failed, allowing them to read or write memory outside intended limits or escalate privileges.

04Vulnerable & Fixed Patterns

Vulnerable pattern
def allocate_buffer(user_size):
    # user_size comes from untrusted input (e.g., HTTP parameter)
    # Assume it's a large positive number from a 64-bit source
    buffer_size = int(user_size) & 0xFFFF  # Truncate to 16 bits
    buffer = bytearray(buffer_size)
    return buffer

# If user_size is 0x10001, it becomes 0x0001 after truncation
# A 1-byte buffer is allocated instead of the intended larger size

Why it's vulnerable:
The truncation silently reduces the buffer size without validation. If the truncated value is then used to copy data, a buffer overflow can occur.

Fixed pattern
def allocate_buffer(user_size):
    # Validate the input range before conversion
    MAX_BUFFER_SIZE = 1024 * 1024  # 1 MB limit
    try:
        size = int(user_size)
        if size < 0 or size > MAX_BUFFER_SIZE:
            raise ValueError("Buffer size out of acceptable range")
        buffer = bytearray(size)
        return buffer
    except (ValueError, TypeError) as e:
        raise ValueError(f"Invalid buffer size: {e}")
Vulnerable pattern
function process_user_id($user_id) {
    // $user_id comes from $_GET or $_POST
    // Assume it's expected to be a small positive integer
    $id = (int)$user_id;  // Implicit conversion
    
    // If $user_id is "-1", it converts to -1
    // If used in a query without further checks, it may bypass logic
    $query = "SELECT * FROM users WHERE id = " . $id;
    return $query;
}

Why it's vulnerable:
The cast to int does not validate the range or sign. A negative value or an out-of-range value may pass through and cause unexpected query behavior or access control bypass.

Fixed pattern
function process_user_id($user_id) {
    // Validate before conversion
    $id = filter_var($user_id, FILTER_VALIDATE_INT, [
        "options" => ["min_range" => 1, "max_range" => PHP_INT_MAX]
    ]);
    
    if ($id === false) {
        throw new InvalidArgumentException("Invalid user ID");
    }
    
    // Use parameterized query
    $stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
    $stmt->execute([$id]);
    return $stmt->fetchAll();
}

05Prevention Checklist

Validate numeric input ranges
before any conversion; reject values outside the expected minimum and maximum.
Use explicit, type-safe conversions
rather than relying on implicit casts; check the result for overflow or loss of precision.
Avoid mixing signed and unsigned types
in arithmetic or comparisons; be explicit about signedness expectations.
Use parameterized queries or prepared statements
for database operations so that numeric values are handled safely, independent of conversion artifacts.
Apply bounds checks after conversion
, not before, to catch any values that became out-of-range due to the conversion itself.
Use static analysis tools
to detect implicit conversions and type mismatches in security-sensitive code paths.

06Signs You May Already Be Affected

Look for unexpected behavior in access control decisions, buffer overflows in logs, or crashes when processing edge-case numeric values (very large numbers, negative numbers where only positive are expected, or values near type boundaries). If you see queries or memory operations behaving differently than their input suggests, a numeric conversion issue may be at play.

07Related Recent Vulnerabilities