详解php比较操作符的安全问题

时间:2021-05-25

php的比较操作符有==(等于)松散比较,===(完全等于)严格比较,这里面就会引入很多有意思的问题。

在松散比较的时候,php会将他们的类型统一,比如说字符到数字,非bool类型转换成bool类型,为了避免意想不到的运行效果,应该使用严格比较。如下是php manual上的比较运算符表:

例子 名称 结果$a == $b 等于 TRUE,如果类型转换后 $a 等于 $b。$a === $b 全等 TRUE,如果 $a 等于 $b,并且它们的类型也相同。$a != $b 不等 TRUE,如果类型转换后 $a 不等于 $b。$a <> $b 不等 TRUE,如果类型转换后 $a 不等于 $b。$a !== $b 不全等 TRUE,如果 $a 不等于 $b,或者它们的类型不同。$a < $b 小与 TRUE,如果 $a 严格小于 $b。$a > $b 大于 TRUE,如果 $a 严格大于 $b。$a <= $b 小于等于 TRUE,如果 $a 小于或者等于 $b。$a >= $b 大于等于 TRUE,如果 $a 大于或者等于 $b。

0x01 安全问题

1 hash比较缺陷

php在处理hash字符串的时候会用到!=,==来进行hash比较,如果hash值以0e开头,后边都是数字,再与数字比较,就会被解释成0*10^n还是为0,就会被判断相等,绕过登录环节。

root@kali:~/tool# php -r 'var_dump("00e0345" == "0");var_dump("0e123456789"=="0");var_dump("0e1234abc"=="0");'
bool(true)
bool(true)
bool(false)

当全是数字的时候,宽松的比较会执行尽力模式,如0e12345678会被解释成0*10^12345678,除了e不全是数字的时候就不会相等,这能从var_dump("0e1234abc"=="0")可以看出来。

2 bool 欺骗

当存在json_decode和unserialize的时候,部分结构会被解释成bool类型,也会造成欺骗。json_decode示例代码:

$json_str = '{"user":true,"pass":true}';$data = json_decode($json_str,true);if ($data['user'] == 'admin' && $data['pass']=='secirity'){ print_r('logined in as bool'."\n");}

运行结果:

root@kali:/var/e!

比较多种类型

运算数 1 类型 运算数 1 类型 结果 null或string string 将NULL转换为 "",进行数字或词汇比较 bool或null 任何其它类型 转换为bool,FALSE<TRUE object object 内置类可以定义自己的比较,不同类不能比较,相同类和数组同样方式比较属性(PHP 4 中),PHP 5 有其自己的说明 string,resource或number string,resource或number 将字符串和资源转换成数字,按普通数学比较 array array 具有较少成员的数组较小,如果运算数 1 中的键不存在于运算数 2 中则数组无法比较,否则挨个值比较(见下例) array 任何其它类型 array总是更大 object 任何其它类型 object总是更大

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章