PHP中MD5弱比较漏洞本质是松散比较==导致0e开头字符串被误判为相等,修复关键在于改用严格比较===、加类型校验、使用hash_equals()及过滤非标量输入。

统一使用严格比较(===)
把所有`==`替换成`===`,强制要求类型和值都一致:
if (md5($a) === md5($b)) { ... }
这样`"0e123456" === "0e789012"`直接返回false,因为两个字符串内容不同。这是最直接、最推荐的第一道防线。
提前类型校验 + 强制转字符串
即使用了`===`,如果输入是数组,`md5([])`会返回`NULL`,可能引发意外绕过。稳妥做法是加一层防护:
- 用`is_string()`确认参数是字符串
- 或显式强转:
(string)$input - 再做`===`比较,避免传入非字符串类型
避免在业务逻辑中直接比较哈希值
更安全的设计是:不拿用户输入直接算MD5再比,而是查数据库取已存储的哈希值,然后用`hash_equals()`做恒定时间比较:
立即学习“PHP免费学习笔记(深入)”;
$stored_hash = get_hash_from_db($username);<br>if (hash_equals($stored_hash, md5($input))) { ... }
`hash_equals()`专为防时序攻击设计,且内部自动做类型安全比较,不会受`0e`干扰。
禁用危险输入类型(如数组)
很多弱比较漏洞配合数组绕过(`md5([])`返回`NULL`)。可在接收参数时主动拦截:
- 用`is_scalar($_GET['a'])`过滤掉数组、对象等非标量类型
- 或对关键参数做`filter_var()`校验,例如只允许字母数字
- 避免让`$_GET`或`$_POST`原样进`md5()`



















