Weakness reference
CWE-843

Access of Resource Using Incompatible Type ('Type Confusion')

Type confusion occurs when code treats a resource variable, object, or memory region as a different type than it actually is. This mismatch can cause the…

01Summary

Type confusion occurs when code treats a resource (variable, object, or memory region) as a different type than it actually is. This mismatch can cause the program to misinterpret data, leading to crashes, memory corruption, or in some cases, arbitrary code execution. Type confusion is particularly dangerous in languages with weak or dynamic typing, or in compiled languages where type safety is not enforced at runtime.

02How It Happens

Type confusion typically arises when:

- A variable or object is cast to an incompatible type without proper validation. - Dynamic typing allows a value of one type to be used where another type is expected, and the code doesn't verify the actual type before operating on it. - Serialized or deserialized data is assumed to be a specific type without checking its actual runtime type. - Memory is reinterpreted as a different structure or type (common in C/C++ with unsafe casts). - A function accepts a generic pointer or untyped parameter and assumes it points to a specific structure.

The core issue is that the code's assumptions about what type a resource is do not match reality, leading to operations that are invalid for the actual type.

03Real-World Impact

When type confusion is exploited, consequences range from denial of service (program crash) to information disclosure (reading unintended memory) to arbitrary code execution (if the confusion allows overwriting function pointers or critical data structures). In web applications, type confusion in deserialization can lead to remote code execution. In compiled software, it can corrupt the heap or stack, enabling attackers to hijack control flow.

04Vulnerable & Fixed Patterns

Vulnerable pattern
def process_user_data(data):
    # Assume data is always a dict, but it could be a string or list
    user_id = data['id']
    user_name = data['name']
    return f"User {user_id}: {user_name}"

# Attacker passes a string instead
result = process_user_data("not_a_dict")

Why it's vulnerable:
The function assumes data is a dictionary without checking its type. If a string or other type is passed, accessing it with [] will either fail or behave unexpectedly, potentially exposing internal state or crashing the application.

Fixed pattern
def process_user_data(data):
    # Validate type before use
    if not isinstance(data, dict):
        raise TypeError("data must be a dictionary")
    
    user_id = data.get('id')
    user_name = data.get('name')
    return f"User {user_id}: {user_name}"

# Now type mismatches are caught early
result = process_user_data({"id": 1, "name": "Alice"})
Vulnerable pattern
<?php
function get_user_email($user_obj) {
    // Assume $user_obj is always a User object
    return $user_obj->email;
}

// Attacker passes a string or array instead
$result = get_user_email("malicious_input");
?>

Why it's vulnerable:
The function assumes $user_obj is an object with an email property. If a string or array is passed, PHP's loose typing may attempt to access it as an object, leading to unexpected behavior, warnings, or memory access violations.

Fixed pattern
<?php
function get_user_email($user_obj) {
    // Validate type before use
    if (!is_object($user_obj) || !($user_obj instanceof User)) {
        throw new TypeError("Expected User object");
    }
    return $user_obj->email;
}

// Now only valid User objects are accepted
$result = get_user_email($user_object);
?>

05Prevention Checklist

Validate input types explicitly
before using them — use isinstance() in Python, is_object() / instanceof in PHP, or equivalent checks in your language.
Use strict type declarations
where available (PHP 7+ type hints, Python type annotations) to catch mismatches at development time.
Avoid unsafe casts
— never cast a pointer or variable to an incompatible type without thorough validation of the underlying data.
Deserialize safely
— when accepting serialized data (JSON, pickle, etc.), validate the structure and types of deserialized objects before use.
Use allowlists for expected types
— if a function should only accept specific types, explicitly check for them rather than assuming.
Enable runtime type checking
— use linters, static analyzers, and type checkers (mypy, Psalm, etc.) to catch type mismatches before deployment.

06Signs You May Already Be Affected

Look for unexpected crashes or "segmentation fault" errors in logs, especially when processing user-supplied data. Unusual error messages about property access on non-objects, or attempts to access array indices on non-arrays, may indicate type confusion. If you see memory corruption symptoms (heap corruption, stack smashing) or unexplained behavior changes after processing specific inputs, type confusion may be involved.

07Related Recent Vulnerabilities