This weakness occurs when code assumes input will always be a specific data type string, integer, array, etc. without validating or safely handling cases where…
This weakness occurs when code assumes input will always be a specific data type (string, integer, array, etc.) without validating or safely handling cases where a different type arrives. An attacker or unexpected system state can send data in an unexpected format, causing the application to crash, behave unpredictably, or expose sensitive information.
02How It Happens
Most programming languages allow data to be passed in multiple formats. A function might expect an integer but receive a string, or expect an array but receive a single value. When code directly uses incoming data without checking its type first, operations designed for one type fail silently or throw unhandled exceptions. This is especially common at API boundaries, form submissions, and configuration file parsing, where external input has no guaranteed structure.
The root cause is usually one of two patterns: either the code assumes a type without validation, or it catches exceptions too broadly and continues with corrupted state. Type-unsafe languages (PHP, JavaScript, Python) are particularly vulnerable because implicit type coercion can mask the problem until it causes a crash or logic error downstream.
03Real-World Impact
Type confusion can lead to application crashes (denial of service), incorrect business logic execution (e.g., a price field treated as a string instead of a number), or information disclosure if error messages reveal internal structure. In some cases, unexpected types can bypass security checks—for example, if a permission check expects an integer user ID but receives an array, the comparison might succeed unexpectedly. While less dramatic than injection attacks, type handling bugs are common in real applications and often go unnoticed until they cause visible failures.
04Vulnerable & Fixed Patterns
Vulnerable pattern
def process_user_age(user_data):
age = user_data['age']
# Assumes age is always an integer
if age >= 18:
return "Adult"
else:
return "Minor"
# If user_data['age'] is a string like "25" or a list,
# the comparison fails or behaves unexpectedly
result = process_user_age({'age': "not_a_number"})
Why it's vulnerable: The code assumes age is an integer and directly compares it without checking the actual type. If a string or other type is passed, the comparison may raise an exception or produce incorrect results.
Fixed pattern
def process_user_age(user_data):
age = user_data.get('age')
# Validate type and convert if necessary
if not isinstance(age, int):
try:
age = int(age)
except (ValueError, TypeError):
raise ValueError("Age must be a valid integer")
if age >= 18:
return "Adult"
else:
return "Minor"
result = process_user_age({'age': "25"})
Vulnerable pattern
<?php
function calculate_discount($order_data) {
$quantity = $order_data['quantity'];
// Assumes quantity is always an integer
$discount = $quantity * 0.1;
return $discount;
}
// If quantity is a string or array, arithmetic behaves unexpectedly
$result = calculate_discount(['quantity' => "abc"]);
?>
Why it's vulnerable: PHP's loose typing allows the multiplication to proceed even if quantity is not a number, resulting in silent type coercion or unexpected values.
Fixed pattern
<?php
function calculate_discount($order_data) {
$quantity = $order_data['quantity'] ?? null;
// Validate type
if (!is_int($quantity) && !is_numeric($quantity)) {
throw new InvalidArgumentException("Quantity must be a number");
}
$quantity = (int) $quantity;
$discount = $quantity * 0.1;
return $discount;
}
$result = calculate_discount(['quantity' => "10"]);
?>
05Prevention Checklist
Validate input type at entry points. Use isinstance() (Python), is_int() / is_array() (PHP), or equivalent type checks before using external data.
Define and enforce expected data structures. Use type hints (Python 3.5+), strict type declarations (PHP 7+), or schema validation libraries (JSON Schema, Pydantic).
Convert types explicitly. If you accept multiple formats, convert to a canonical type immediately and handle conversion errors gracefully.
Avoid silent type coercion. Disable loose comparison operators where possible; use strict equality (=== in PHP, is in Python) to catch type mismatches.
Test with unexpected types. Include test cases that pass strings where integers are expected, arrays where scalars are expected, and null values.
Log and monitor type errors. Catch type-related exceptions and log them; repeated type errors may indicate an attack or misconfiguration.
06Signs You May Already Be Affected
Look for error logs containing TypeError, ValueError, or Uncaught Exception messages that reference type mismatches or unexpected data structures. Unexpected application crashes or 500 errors that occur sporadically when certain users or API clients submit requests may indicate type handling issues. If you see arithmetic or comparison operations producing obviously wrong results (e.g., a discount calculation returning a string instead of a number), type confusion is a likely culprit.