本文共 1347 字,大约阅读时间需要 4 分钟。
编程本身就应该是一门艺术,而安全编程更是一种在刀尖上舞蹈的艺术,不仅要小心脚下的锋利寒刃,更要小心来自网络黑客或攻击者的狂轰乱炸。
- by code artist
例如:
var_dump('0e1327544' == 0); // bool(true)
当密码被md5计算后,可能会以"0e"开头,下面这个例子可以绕过密码验证。
经过我的验证PHP 7.1.x后没有这种问题。更安全的hash比较:
可以使用内置函数hash_equals()来比较hash值。(PHP版本必须是5.6及其以上)if (hash_equals($password_from_db, md5($password)) { .....// other logic }
json_decode和unserialize函数可能将部分结构解析成bool值,造成一些比较上的缺陷。
先举例json_decode的案例:
执行结果为:login success
这样利用bool比较的漏洞就绕过了登录或者授权验证。unserialize过程相逆,结果类似,也会出现安全问题。
正确的做法还是使用"==="来进行比较,这不光是php,包括一些其他脚本语言或者静态语言,都请严谨地使用全等于符号进行比较。
PHP虽然是弱类型语言,但是数据类型也有数值范围。对于整型而言,最大值为PHP_INT_MAX(即9223372036854775807)
攻击者可以利用最大值越界,绕过一些验证,如登录、账号充值等等。举例:
$a = 9223372036854775807;$b = 9223372036854775827;var_dump($a === $b); // bool(true)var_dump($a % 100); // int(0)
由此,可见全等号(===)也不是万能的,具体场景下要更小心。经验证,PHP7.1.x后不会出现该问题,5.x的可能出现。
在实际业务逻辑里面一定要注意判断最大值问题,避免越界带来的问题。
当使用超长浮点数变量的时候,PHP也会出错。
同理,2.999999999999也会被当成3,这就是超越浮点数精度造成的偏差。
解决办法有很多,最简单的就是用is_int()函数进行判断,如果不是整型,则报错或做错误处理。
当用case判断数字的时候,switch会把参数转换成int类型进行计算,代码如下:
最后输出:1 hacker here!
所以,请使用is_numeric()函数进行判断,保证数据类型如预期的一致。
总的来说,PHP工程师对于这种弱类型语言的使用上要更加小心,虽然平时写起业务来“短平快”,但安全编程也不要忘记,能用上hint的高版本PHP就进行标注清楚入参、出参,让PHP代码更加健壮。
转载地址:http://eksuz.baihongyu.com/