现在用php开发的网站数目量仍然庞大,从安全编程的角度,符合规范的php代码应该严谨。然而在很多时候由于开发人员编写代码没有很好的安全思路,会导致php代码产生一些容易被利用、被绕过的地方。
1.关于“=”、“==”、“===”的使用
=:赋值
==:比较(弱,比较前会把类型强制转换再比较)
===:比较(强,比较所有包括值和类型)
当有必要进行严格使用强类型比较的时候,开发人员却在编写代码时使用了若比较“==”,就算类型不正确也会被执行成功,因此产生风险。
用一个例子说明:
·某php代码为
if($_GET[‘name’]!=$_GET[‘password’])
{
if(MD5($_GET[‘name’])==MD5($_GET[‘password’]))
{
echo $flag;
}
echo ‘?’;
}
使用“==”,找到两个MD5值前两位0e相同的字符串输入,就可以满足明文不同但是MD5值相同,php会以为他们都是0。
if($_GET[‘name’]!=$_GET[‘password’])
{
if(MD5($_GET[‘name’])===MD5($_GET[‘password’]))
{
echo $flag;
}
echo ‘?’;
}
使用“===”,这时候会对比所有属性,那么可以使用数组的思路,因为数组不能进行MD5运算,结果会变成null,这样输入两个数组如name[]=1&password[]=2也实现了明文不同但是MD5相同
【危害】如果后台验证存在类似对比不当缺陷,会有安全风险
2.php使用intval()函数过滤sql
intval是用来做进制转换的
3.strpos()函数,判断第一次出现的位置
可以使用换行进行绕过,也就是前面加上“%0a”
4.in_array()d函数,从数组中判断是否含有目标字符
注意到这个函数有三个参数,第三个参数应该被设置为true,否则相当于使用“==”不会检测类型,
存在绕过的问题
in_array($x1,$x2,strict:true)
5.preg_match()函数,它只能处理字符串。那么如果传数组进去就会报错
6.str_replace()函数,用来过滤sql的
双写过滤词就可以绕过,比如过滤apple,双写之后就是apappleple
如果使用这个函数不当,极有可能产生任意文件读取,因为过滤能被绕过。比如过滤“../”、“./”就可以使用双写等方式绕过,就可以查看任意路径