Insecure Hash Comparison with Type Juggling in f.php
Bug
The code compares a user-supplied key (via $_POST['key']) to a stored MD5 hash using the == operator:
if ($link['key'] == md5($_POST['key'])) {
$password_challenged = true;
}
MD5 is cryptographically broken – it's fast, unsalted, and vulnerable to: Brute-force attacks, Rainbow table lookups, Collision attacks.
The == operator in PHP performs type juggling. If both values look like numbers, PHP converts them to numbers before comparing. Some MD5 hashes begin with "0e...", which PHP interprets as scientific notation, i.e., 0e1234 → 0.
Example :
$link['key'] = "0e830400451993494058024219903391"; // md5("QNKCDZO")
$_POST['key'] = "240610708"; // md5("240610708") = "0e462097431906509019562988736854"
Then...
if ("0e830..." == "0e462...") → if (0 == 0) → true ✅
Even though the original strings are different, PHP interprets both hashes as float(0) — this is type juggling.
Fix
Always use hash_equals() when comparing hashes:
if (hash_equals($link['key'], hash('sha256', $_POST['key']))) {
$password_challenged = true;
}
Aspect |
md5 + ==
|
sha256 + ==
|
sha256 + hash_equals() |
---|---|---|---|
Secure hash |
|
|
|
Type safe compare |
|
|
|
Recommended? |
|
|
|