Lion Cipher Lab

Exploit and fix a PHP type-juggling authentication bypass

Why it matters

PHP still runs a large share of the web, and the single most PHP-specific footgun is the loose comparison operator. When you write `==` or `!=`, PHP does not compare the two values as they are -- it TYPE-JUGGLES them: it picks a common type, silently coerces BOTH operands to it, and only then compares. That is convenient right up until the values are secrets. A login that checks `md5($password) == $stored_hash`, an API gate that checks `$token == $SECRET`, a reset flow that checks `strcmp($code, $real) == 0` -- every one of these can be walked straight past by an attacker who never learns the…

What you'll learn

Steps in this lab

  1. The one idea: == in PHP compares after it coerces types
  2. Get PHP running (local install OR the Docker image)
  3. See the juggling for yourself (before any auth code)
  4. Build the vulnerable auth endpoint
  5. Exploit it: six bypasses, no password -- measure N/N
  6. The version trap: run the SAME code on PHP 8 (honest negative)
  7. Fix it: strict ===, hash_equals(), password_verify(), type checks
  8. Re-measure: run the identical attack against the fix
  9. The limits of the fix -- what each piece does NOT do
  10. Do it better -- the code-review reflex

Open the full interactive lab →