← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Type Coercion

php CWE-704 OWASP A3:2021 CVSS 8.1 PHP 7.0+ Intermediate

Also Known As

PHP type juggling implicit casting type coercion PHP

TL;DR

PHP's automatic conversion between types can produce unexpected comparison results, leading to logic bugs and security bypasses.

Explanation

PHP's loose comparison operator == performs type juggling — '0e123' == '0e456' evaluates to true because both are treated as scientific notation floats equal to zero. This has historically enabled authentication bypasses in MD5 hash comparisons. Similarly, 0 == 'foo' is true in PHP 7 (though fixed in PHP 8). Use strict comparison (===) for all security-sensitive comparisons, enable strict_types, and be aware of how in_array() and array_search() behave without the strict parameter.

Common Misconception

PHP type coercion only affects comparisons. Type coercion also affects arithmetic, string concatenation, and function arguments in non-strict mode — "5 apples" + 2 equals 7, and passing "42abc" to an int parameter silently becomes 42.

Why It Matters

PHP's type juggling silently converts values between types — understanding coercion rules prevents security bypasses (type juggling attacks) and logic bugs caused by unexpected equality.

Common Mistakes

  • Using == with mixed types — '0e1234' == '0e5678' is true (both are 0 in scientific notation).
  • in_array() without the strict third parameter — in_array(0, ['a', 'b']) returns true in PHP 7.
  • switch statements coercing types — switch('0') matches case false.
  • Not enabling strict_types — PHP silently coerces string '42' to int 42 without it.

Avoid When

  • Avoid relying on implicit coercion for security checks — '0' == false == null under loose comparison.
  • Do not use type coercion as a sanitisation strategy — cast after validating, not instead of validating.

When To Use

  • Understand PHP's type coercion rules when working with legacy code that omits strict_types.
  • Use explicit casting when you intentionally need a value in a specific type — (int)$_GET['page'].

Code Examples

✗ Vulnerable
if (md5($input) == $storedHash) { /* bypass with '0e...' hashes */ }
✓ Fixed
if (hash_equals($storedHash, md5($input))) { /* constant time + strict */ }

Added 15 Mar 2026
Edited 31 Mar 2026
Views 190
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 6 pings M 5 pings T 5 pings W 5 pings T 6 pings F 6 pings S 1 ping S 2 pings M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
ChatGPT 136 Perplexity 14 Amazonbot 14 Google 6 Unknown AI 5 SEMrush 3 Ahrefs 2
crawler 178 crawler_json 1 pre-tracking 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
Enable strict_types=1 in every file to prevent PHP from silently coercing '5abc' to 5 — without it, passing a string to an int parameter succeeds with unexpected results
📦 Applies To
PHP 7.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
fn(int $n) called with '5abc' silently truncating to 5 without strict_types; implicit bool→int coercion in arithmetic; comparison bugs from string→number coercion
Auto-detectable: ✓ Yes phpstan psalm rector
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: High ✗ Manual fix Fix: Medium Context: Function Tests: Update
CWE-704 CWE-697

✓ schema.org compliant