PHP 的弱类型特性有时会导致意外的行为,特别是在类型比较时。这些特性可以被利用来绕过一些预期的安全检查。以下是一些常见的 PHP 弱类型绕过技巧及其解释:
类型介绍
1. 类型比较 (==
vs ===
)
在 PHP 中,==
是松散比较,而 ===
是严格比较。松散比较会在比较前进行类型转换,而严格比较不会。
// 示例
var_dump(0 == '0'); // 输出: bool(true)
var_dump(0 === '0'); // 输出: bool(false)
2. 字符串与数字比较
PHP 在进行松散比较时,会将字符串转换为数字进行比较(如果可能)。
// 示例var_dump('0e123' == '0e456'); // 输出: bool(true),因为两者都被视为科学计数法表示的0var_dump('1e10' == '10000000000'); // 输出: bool(true),因为两者都被视为数值1e10
这种特性可以被用来绕过一些基于哈希值比较的验证,例如在某些密码重置功能中。
3. 布尔类型与字符串比较
PHP 在松散比较时,会将字符串 'false'
、'0'
、''
(空字符串)等视为布尔值 false
。
// 示例var_dump('' == false); // 输出: bool(true)var_dump('0' == false); // 输出: bool(true)var_dump('false' == false); // 输出: bool(true)
4. 数组与布尔值比较
在松散比较中,空数组 []
会被视为布尔值 false
。
// 示例
var_dump([] == false); // 输出: bool(true)
var_dump([] == 0); // 输出: bool(true)
var_dump([] == '0'); // 输出: bool(true)
5. 对象与布尔值比较
如果一个对象在松散比较中被转换为布尔值 false
(例如,通过 empty()
函数),它会在比较中被视为 false
。
// 示例
class MyClass {}
$obj = new MyClass();
var_dump($obj == false); // 输出: bool(false),但注意 empty($obj) 会返回 true
防御措施
为了防范这些弱类型比较带来的问题,可以采取以下措施:
- 使用严格比较 (
===
):始终使用严格比较来避免类型转换带来的意外行为。 - 验证输入:严格验证用户输入,确保它们符合预期的类型和格式。
- 避免使用不安全的比较:例如,避免使用
==
来比较哈希值或密码。 - 类型转换:在比较之前显式地进行类型转换,以确保比较操作基于相同的类型
绕过措施
1.0e绕过
常见的Md5碰撞
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675