今天积分系统被注射了,幸好没造成什么损失。问题在下面这一条语句上:
$type = ( in_array( $_GET['t'], array(1,2,3) ) ) ? $_GET['t'] : 0; //对$type入库操作
先判断参数t是否在1,2,3中,如果不是$type则为0。看上去没什么问题,因为参数t被定死了,无法进行构造注入语句。
但是PHP弱类型语言,两个不同类型的变量比较,其中一个变量会进行转换,也就是说$_GET['t']在与整形1,2,3作比较前,会将字符串转成整形。
字符串转成数字型时,如果字符串开头不是数字形式,就转成0(例如intval('zyday')==>0 );如果该字符串开头是数字形式的,就会转成该数字,后面的非字符串被去掉(例如intval( '111zyday')==>111 )。只要开头为1,2,3中任意一个,后面随便接什么都行。
示例:
提交参数 t='and 1=2 union select ';
in_array( $_GET['t'], array(1,2,3) ) //返回false
提交参数t='1 and 1=2 union select ';
in_array( $_GET['t'], array(1,2,3) ) //返回true 漏洞产生
我很惭愧,作为一名PHP开发者,保证写出的代码没有安全问题是最起码的底线。今天出了这么大的纰漏,竟然还大言不惭地说热爱网络安全,无地自容。基本功差、执行力差、不主动、说到做不到是我最致命的弱点,长此以往即使再过10年水平也就和刚毕业一样。自身的问题很多很多,在此纪录一下,以此反思、勉励。