许多人声称PHP是那所谓的“最好的语言”哪,然而,它具备的弱类型的特性,加上其松散的内置函数处理方式,着实给网站安全领域带来了别具一格与众不同很具特色的风险以及挑战。
弱类型的自动转换机制
PHP的弱类型表明变量不存在固定的数据类型,在程序运行之际,PHP会自行开展类型转换,举例而言,当把用户借助GET或者POST提交的字符串“123abc”转化为整数时,PHP会自字符串起始处读取数字,直至碰到非数字字符,其结果会变为123 。
$param = 1; $param = array(); $param = "stringg";
这般自动转换是出于便利之目的,然而倘若开发者对其规则缺乏了解,那么便极易滋生漏洞。举例而言,在处理用户ID之时,或是金额,又或是数量之际,本应当作为字符串的输入却被意外地转换成为数字,如此一来便有可能致使数据出现错误,抑或是逻辑被绕过,进而为攻击者造就了机会。
比较运算符的隐藏问题
$a=null;$b=flase ; //true $a='';$b=null; //true
在PHP里,当运用“==”对不同类型的变量予以比较时,会先开展类型转换,之后再做判断。字符串“0e123”会被视作科学计数法的0哦,要是另一个值在转换之后同样是0,那么“0e123” == “0”这种情况就会成立啦,即便它们看上去全然不一样。
有安全校验,似比较密码哈希值时,若攻击者可供给“0e”开篇之字符串,便似会绕过验证。这般因松散比较致使地安全问题,于早期诸多网络应用里屡见习闻。
0=='0' //true 0 == 'abcdefg' //true 0 === 'abcdefg' //false 1 == '1abcdef' //true
哈希函数与数组参数
md5()、sha1()等哈希函数运用来针对字符串而设计,然而要是传入一个体现为数组的值即像是在md5($_GET[‘key’])这种状况下,并且其中的$_GET[‘key’]确定是数组的时候,这函数并不会产生报错的情况,反而是得到显示为NULL的结果,这样所造成的结果就是任意的两个数组所呈现出来的md5值都会等同于“相等”的状态。
"0e132456789"=="0e7124511451155" //true "0e123456abc"=="0e1dddada" //false "0e1abc"=="0" //true
攻击者在某些网站的漏洞利用场景里,能够传递数组致使哈希比较失效,进而绕过身份验证,此特性在一些CTF(夺旗赛)题目以及真实漏洞当中,曾被直接考察并利用。
字符串的意外数值转换
"0x1e240"=="123456" //true "0x1e240"==123456 //true "0x1e240"=="1e240" //false
当对字符串跟数字进行那个松散比较的处理之际,PHP会把字符串试着去转换成为数字。那个字符串“abc”会被转变成整数0,字符串“1def”则会被转变成1。要是在代码里用“==”来比较“abc”跟0,结果是真。
这不免致使相当严重的逻辑差错,举例来讲进行对用户键入录入成分开展是否属某一种特定数值的查验之际了因用户键入的并非是数字类字符之串则没准会错定为零进而步入非预先期望的代码分支板块最终破坏程序正常的业务逻辑内容 。
$var = 5; 方式1:$item = (string)$var; 方式2:$item = strval($var);
类型转换函数的边界
var_dump(intval('2')) //2
var_dump(intval('3abcd')) //3
var_dump(intval('abcd')) //0
用于进行显式转换的 intval()、strval() 等函数,是存在其自身规则的。intval(“123abc?”) 所得到的结果是 123。这种转换是从字符串的起始位置发起,并在碰到非数字字符的时候就会停止。看起来好像比较明确,然而假如开发者错误地认为它能够验证整个字符串是不是纯数字,实际上就会埋下某种隐患。
验证输入是不是纯数字ID之际,运用intval变换而后直接去比较,或许没办法辨识“123abc”这种非法的输入 ,这是由于它被转变成了合法的数字123 ,借此让恶意的输入得以蒙混过关 。
if(intval($a)>1000) {
mysql_query("select * from news where id=".$a)
}
内置函数的松散参数处理
一些内置函数对于参数类型的要求并非十分严格,比如说,in_array()函数在开展非严格比较(此为默认情况)的时候,会运用松散比较来判定值是不是在数组当中,这极有可能致使0与字符串“abc”(经转换之后变为0)出现误匹配的状况。
再一个例子为strcmp()函数,其本是用来比较字符串的,然而要是传入数组等并非字符串的参数,就会返回NULL。在某些编程逻辑里面,NULL跟0的不严谨比较有可能成立,进而被攻击者借助从而绕过安全检查。
$array1[] = array(
"foo" => "bar",
"bar" => "foo",
);
$array2 = array("foo", "bar", "hello", "world");
var_dump(md5($array1)==var_dump($array2)); //true
对那些常常应对用户输入以及安全验证处理之举止有所作为的开发者来讲,在PHP项目范畴内,你觉得其中最应当被完全杜绝或者替换掉的某一个内置函数或者编程习性究竟是什么呢?欢迎于评论区这儿分享你的观点看法,要是自以为本文具备一定助益功效,也请点赞予以扶持。


