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

Type Coercion in Authentication Checks

Security PHP 4.0+ Advanced
debt(d5/e2/b3/t8)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches' (d5), phpstan and semgrep rules per detection_hints can flag == on token/hash comparisons, but default PHP linters don't catch it — needs a security-aware SAST rule.

e2 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch' (e1) but slightly higher (e2) because quick_fix involves swapping == for ===, hash_equals(), or password_verify() across multiple comparison sites — each fix is one line but you must find them all.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3), applies to authentication code paths specifically; doesn't shape the whole system but does require ongoing vigilance in every auth-touching component.

t8 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7) leaning catastrophic (t8) — the misconception that strcmp() returns 0 on match (intuitively 'success') colliding with 0 == false is exactly the contradiction-of-similar-concept pattern; the 'obvious' comparison operators silently authenticate attackers via magic hashes.

About DEBT scoring →

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 55
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 1 ping F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 1 ping F 0 pings S 2 pings S 0 pings M 1 ping T 4 pings W 1 ping T 1 ping 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 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 7 Scrapy 7 Perplexity 5 Unknown AI 4 SEMrush 4 ChatGPT 3 Google 3 Ahrefs 3 Claude 2 Meta AI 1 PetalBot 1
crawler 36 crawler_json 2 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