PHP Type Juggling

What is PHP Type Juggling?

is the automatic conversion between different data types by PHP when performing operations or comparisons. This behaviour is rooted in PHP's nature as a loosely-typed language, designed to make development easier but often leading to unexpected results and potential security vulnerabilities if not managed properly.

Key Concepts:

  • Comparisons:

    • Loose Comparison(==):

"123" == 123   // true
"0" == false   // true
null == ""     // true
var_dump(0 == 'test'); // true, because 'test' is converted to 0
var_dump('0' == 0);    // true, both are treated as integers
  • Arithmetic operations:

    • performing math operations between strings numbers causes strings to be converted to numbers

"10" + 5    // 15
"10abc" + 5 // 15
  • Boolean Contexts:

    • Non-boolean values are converted to true or false based on their value.

if ("0") {.....}    // Evaluates to false
if (0) {......}     // Evaluates to false
if ("foo") {.....}  // Evaluates to true
if (bool(False)) {} // Evaluates to false
if (bool(None)) {}  // Evaluates to false
if (bool(0))  {}    // Evaluates to false
if (bool("")) {}    // Evaluates to false
if (bool(())) {}    // Evaluates to false
if (bool([])) {}    // Evaluates to false
if (bool({})) {}    // Evaluates to false
  • String Operations:

    • Concatenating numbers with strings converts numbers to strings.

How Type Juggling Works

  1. String to Number:

    • Non-numeric strings are partially converted to numbers until an invalid character is encountered.

Boolean to Integer:

  1. Loose Comparison:

    • PHP converts both operands to a common type for comparison.

  1. Strict Comparison:

    • Compares both value and type, avoiding type juggling.

Identifying Type Juggling

Source Code Review & Analysis

  1. Code Review:

    • Look for operations between different types, especially comparisons.

    • Identify any loose comparisons (==, !=) that could cause unexpected results.

    • Examine the use of user inputs in operations and comparisons.

    • Review functions or methods where types are not explicitly handled.

  2. Static Analysis Tools:

    • Use tools like PHPStan or Psalm to identify potential type juggling issues by analyzing code for type inconsistencies.

  3. Explicit Type Declarations:

    • Ensure proper type hints and declarations (e.g., function parameters, return types) are used where possible.

  4. Testing and Debugging:

    • Test with varied inputs to observe behaviour. Use var_dump() similar functions to print variable types and values before and after operations.

Why Did This Happen?

PHP automatically tries to convert types based on context:

  • PHP converts the string to a number when you try to perform an arithmetic operation on a string containing numeric characters.

  • "123" is a valid numeric string, so PHP treats it as an integer 123 and adds 1, resulting in 124.

External Testing and Observation

  • Fuzzing Testing:

  • Behavioural Analysis:

    • Compare the application's responses to different types of input. Check for discrepancies in behaviour when inputs are of different types but logically similar (e.g., "0" vs. 0).

  • Boundary Testing:

    • Test edge cases where type boundaries might be crossed, such as large numbers, special characters, or unexpected boolean values.

Exploiting Type Juggling

Authentication Bypass:

Weak Hash Comparisons:

Hash comparisons using == can be bypassed by crafting inputs that evaluate the same numeric value.

Array Key Manipulation:

Unexpected Value Substitution:

Mitigation Strategies

  1. Use Strict Comparisons (===):

    • Always use strict comparisons to avoid type juggling.

  1. Explicit Type Casting:

  1. Input Validation and Sanitization:

    • Validate and sanitize input to ensure it matches the expected type.

  1. Type Declarations and Hints:

    • Use type hints in function parameters and return types to enforce correct types.

  1. Avoid Implicit Conversions:

    • Write code that avoids relying on PHP's implicit type conversions.

Last updated