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

Type Coercion in Authentication Checks

security PHP 4.0+ Advanced

TL;DR

PHP's loose comparison (==) coerces types — '0e123' == '0e456' (both 0 in scientific notation), and 0 == 'admin' — always use === for authentication comparisons.

Explanation

PHP's == operator uses type juggling. Classic attacks: (1) Magic hash collision: two MD5 hashes starting with 0e (like 0e462097431906509019562988736854) are both '0' in scientific notation, making them == equal. (2) 0 == 'anything' because PHP coerces 'anything' to 0. (3) True == 'anything'. The fix: always use === (strict equality) for password, token, and hash comparisons. Use hash_equals() for timing-safe string comparison. PHP's password_verify() and hash_equals() are safe. Never compare hashes with == or strcmp().

Common Misconception

Using strcmp() for hash comparison is secure — strcmp() returns 0 (falsy) on match, but 0 == false in PHP, and it's vulnerable to timing attacks. Use hash_equals().

Why It Matters

Type coercion in authentication allows trivially bypassing password checks, token validation, and hash comparisons with crafted inputs.

Common Mistakes

  • Using == to compare password hashes — magic hash bypass.
  • Using strcmp() for security comparisons — timing attack + type coercion.
  • Not using hash_equals() for HMAC verification.

Code Examples

✗ Vulnerable
// Vulnerable: 0 == 'admin' is TRUE in PHP
if ($token == $expectedToken) { /* bypassable */ }

// Vulnerable: magic hash
$hash = md5($password); // e.g. '0e123...'
if ($hash == $storedHash) { /* 0e... == 0e... */ }
✓ Fixed
// Always strict comparison:
if ($token === $expectedToken) { /* correct */ }

// For timing-safe hash comparison:
if (hash_equals($storedHash, $computedHash)) { /* safe */ }

// For passwords, always use password_verify:
if (password_verify($input, $storedHash)) { /* safe */ }

Added 22 Mar 2026
Views 29
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Amazonbot 6 Perplexity 5 Unknown AI 4 ChatGPT 3 Google 2 Ahrefs 1 SEMrush 1
crawler 20 pre-tracking 2
DEV INTEL Tools & Severity
🔴 Critical ⚙ Fix effort: Low
⚡ Quick Fix
Replace all == with === for security comparisons. Use hash_equals() for hash comparison. Use password_verify() for passwords. Never compare tokens with strcmp().
📦 Applies To
PHP 4.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
== \$.*[Tt]oken|== \$.*[Hh]ash|strcmp.*password
Auto-detectable: ✓ Yes phpstan semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✓ Auto-fixable Fix: Low Context: Line Tests: Update
CWE-697 CWE-287 CWE-916

✓ schema.org compliant