Weakness reference
CWE-704

Incorrect Type Conversion or Cast

Type conversion weaknesses occur when software converts data from one type to another in a way that produces unexpected or unsafe results. In loosely-typed…

01Summary

Type conversion weaknesses occur when software converts data from one type to another in a way that produces unexpected or unsafe results. In loosely-typed languages like PHP and Python, implicit type conversions can silently change the meaning of data, allowing attackers to bypass security checks, authentication logic, or input validation. This is particularly dangerous when type coercion happens during comparisons or security-critical operations.

02How It Happens

Most modern languages support type conversion—changing a string to an integer, a boolean to a string, and so on. The problem arises when:

1. Implicit conversions are relied upon
without explicit checking. A loosely-typed language may automatically convert "0" to the integer 0, or "admin" to true, in ways the developer didn't anticipate. 2. Comparisons use loose equality
instead of strict equality. In PHP, 0 == "string" evaluates to true; in Python, similar surprises can occur with mixed-type comparisons. 3. Type assumptions are made without validation.
Code assumes a variable is an integer and performs arithmetic or array indexing on it, but receives a string or array instead. 4. User input is cast without sanitization.
A developer casts user input to an expected type (e.g., (int)$_GET['id']) but doesn't verify the cast succeeded or produced a sensible result.

The attacker exploits these gaps by supplying input of an unexpected type, causing the conversion to produce a value that bypasses security logic.

03Real-World Impact

Type conversion bugs can lead to authentication bypass (logging in as a different user), authorization bypass (accessing resources you shouldn't), SQL injection (if type coercion affects query construction), or logic errors that expose sensitive data. For example, a loose comparison in a password verification function might allow an attacker to log in with a crafted input that coerces to true. In array or object contexts, type confusion can cause the wrong data to be accessed or modified.

04Vulnerable & Fixed Patterns

Vulnerable pattern
def verify_user(user_id, password_hash):
    stored_hash = get_hash_from_db(user_id)
    # Vulnerable: loose comparison with ==
    if password_hash == stored_hash:
        return True
    return False

# Attacker supplies password_hash as integer 0
# If stored_hash is a falsy string, 0 == "" evaluates to True
result = verify_user(1, 0)

Why it's vulnerable:
Python's == operator performs type coercion; 0 == "" and 0 == False both evaluate to True, allowing an attacker to bypass the hash check by supplying a type that coerces to a falsy value matching the stored hash's falsy interpretation.

Fixed pattern
def verify_user(user_id, password_hash):
    stored_hash = get_hash_from_db(user_id)
    # Fixed: strict comparison with == on same types
    # Ensure password_hash is a string before comparison
    if not isinstance(password_hash, str):
        return False
    if password_hash == stored_hash:
        return True
    return False
Vulnerable pattern
<?php
function check_admin($user_role) {
    // Vulnerable: loose comparison
    if ($user_role == "admin") {
        return true;
    }
    return false;
}

// Attacker supplies array or object; PHP coerces to string "Array"
// But also: if $user_role is 0 or null, loose == may behave unexpectedly
$result = check_admin($_GET['role']);
?>

Why it's vulnerable:
PHP's loose == operator coerces types aggressively. An array coerces to the string "Array", and numeric strings coerce to integers. An attacker can supply input that coerces to a value matching the comparison target.

Fixed pattern
<?php
function check_admin($user_role) {
    // Fixed: strict comparison with === and type check
    if (is_string($user_role) && $user_role === "admin") {
        return true;
    }
    return false;
}

$result = check_admin($_GET['role']);
?>

05Prevention Checklist

Use strict equality operators
(=== in PHP, is with type checking in Python) instead of loose equality (==, !=) in security-critical comparisons.
Validate input type explicitly
before use. Check is_string(), is_int(), isinstance(), etc., and reject or convert unexpected types.
Cast only when necessary, and validate the result.
If you must cast user input to an integer, verify the cast succeeded and the result is in an expected range.
Avoid relying on implicit conversions.
Be explicit: convert a string to an integer using a function like int() or intval(), not by relying on automatic coercion in arithmetic.
Use type hints and static analysis.
In Python, use type annotations; in PHP, use strict types (declare(strict_types=1);) to catch type mismatches early.
Test with unexpected input types.
Include test cases where you pass strings where integers are expected, arrays where scalars are expected, and so on.

06Signs You May Already Be Affected

Look for unexpected authentication or authorization bypasses—users logging in with incorrect passwords, or accessing resources they shouldn't. Check application logs for requests with unusual input types (arrays or objects in fields that should be strings or numbers). Review security-critical code for loose equality operators or missing type checks before comparisons or casts.

07Related Recent Vulnerabilities