随着代码安全的普及,越来越多的开发人员知道了如何防御sqli、xss等与语言无关的漏洞,但是对于和开发语言本身相关的一些漏洞和缺陷却知之甚少,于是这些点也就是我们在Code audit的时候的重点关注点。本文旨在总结一些在PHP代码中经常造成问题的点,也是我们在审计的时候的关注重点。(PS:本文也只是简单的列出问题,至于造成问题的底层原因未做详细解释,有兴趣的看官可以自行GOOGLE或者看看底层C代码。知其然,且知其所以然)
查看php源码,其实我们能发现,php读取、写入文件,都会调用php_stream_open_wrapper_ex来打开流,而判断文件存在、重命名、删除文件等操作则无需打开文件流。
我们跟一跟php_stream_open_wrapper_ex就会发现,其实最后会使用tsrm_realpath函数来将filename给标准化成一个绝对径。而文件删除等操作则不会,这就是二者的区别。
所以,如果我们传入的是文件名中包含一个不存在的径,写入的时候因为会处理掉“../”等相对径,所以不会出错;判断、删除的时候因为不会处理,所以就会出现“No such file or directory”的错误。
extract函数从数组导入变量(如\$_GET、 \$_POST),将数组的键名作为变量的值。而parse_str函数则是从类似name=Bill&age=60的格式字符串解析变量.如果在使用第一个函数没有设置EXTR_SKIP或者EXTR_PREFIX_SAME等处理变量冲突的参数时、第二个函数没有使用数组接受变量时将会导致变量覆盖的问题
intval函数进去取整时,是直到遇上数字或者正负号才开始进行转换,之后在遇到非数字或者结束符号(\0)时结束转换
is_numeric函数在判断是否是数字时会忽略字符串开头的’ ‘、’\t’、’\n’、’\r’、’\v’、’\f’。
而’.’可以出现在任意,E、e能出现在参数中间,仍可以被判断为数字。也就是说is_numeric(“\r\n\t 0.1e2”)>
TRUE
但是如果传入的两个变量是数组的话,函数会报错返回NULL,如果只是用strcmp()==0来判断的线() 函数传入数组比较绕过
printf()和sprintf()函数中可以通过使用%接一个字符来进行padding功能
例如%10s 字符串会默认在左侧填充空格至长度为10,还可以 %010s 会使用字符0进行填充,但是如果我们想要使用别的字符进行填充,需要使用 ‘ 单引号进行标识,例如 %’#10s 这个就是使用#进行填充(百分号不仅会吃掉’单引号,还会吃掉\ 斜杠)
还有一种情况就是’被转义成了\’,例如输入%’ and 1=1#进入,存在SQL过滤,’被转成了\’
程序本意是要a、b都为数字才会继续,但是当\$a为数字时,会先赋值给\$c,所以可能导致$b绕过检测parse_url与libcurl对与url的解析差异可能导致ssrf
。因此当代码对进行解析时,PHP获取的host是允许访问的域名,而最后调用libcurl进行请求时则是请求的域名,可以造成ssrf绕过
网友评论 ()条 查看