大多数漏洞的形成原因主要都是未对输入数据进行安全验证或对输出数据未经安全处理,比较严格的数据验证方式是:
- 对数据进行精确匹配
- 接收白名单验证
- 拒绝黑名单数据
- 对匹配黑名单的数据进行编码
在PHP中可由用户输入的变量列表如下
$_SERVER
$_GET
$_POST
$_COOKIE
$REQUEST
$_FILES
$_ENV
$_HTTP_COOKIE_VARS
$_HTTP_ENV_VARS
$_HTTP_POST_FILES
$_HTTP_POST_VARS
$_HTTP_SERVER_VARS
我们应该对这些输入变量进行检查
命令注入
PHP 执行系统命令可以使用以下几个函数:system、exec、passthru、“、shell_exec、popen、prox_open、pcntel_exec
我们通过在全部程序文件中搜索这些函数,确定函数的参数是否会因为外部提交而改变,检查这些参数是否有经过安全处理。
防范方法:
- 使用自定义函数或函数库来替代外部命令的功能。
- 使用escapeshellarg函数来处理命令参数
- 使用safe_mode_exec_dir指定可执行文件的路径
跨站脚本
反射型跨站常常出现在用户提交的变量接收以后经过处理,直接输出显示给客户端
存储型跨站常常出现在用户提交的变量接收过经过处理后,存储在数据库里,然后又从数据库中读取到此信息输出到客户端。
输出函数经常使用:
echo、print、printf、 vprintf 、 <%=$test%>
对于反射型跨站,因为是立即输出显示给客户端,所以应该在当前的PHP页面检测变量被客户提交之后又无立即显示,这个过冲中变量是否有经过安全检查。
对于存储型跨站,检查变量在输入后入库,又输出显示的这个过程中,变量是否有经过安全检查。
防范方法:
- 如果输入数据只包含字母、数字,那么任何特殊字符都应当组织
- 对输入的数据经过严格匹配,比如邮件格式,用户名只包含英文或者中文、下划线、连字符
- 对输出进行HTML编码,编码规范:
< <;
> >
( (
) )
# #
& &
" "
' '
' %60
文件包含
PHP中可能会出现文件包含函数:include、include_once 、require 、require_once 、 show_source 、highlight_file、 readfile 、 file_get_contents 、fopen 、nt>file
防范方法:
- 对输入数据进行精确匹配,比如根据变量的值确定语言en.php、cn.php、那么这两个文件放在同一个目录下 ' language/ '.$_POST['lang'].'.php',那么检查提交的数据是否是en或者cn是最严格的,检查是否只包含字母也不错
- 通过过滤参数中的/、..等字符
代码注入
PHP可能出现代码注入的函数:eval、preg_replace+/e、assert、call_user_func、call_user_func_array、create——function
查找程序中程序使用这些函数的地方,检查提交变量是否用户可控,有无做输入验证
防范方法:
- 输入数据精确匹配
- 白名单方式过滤可执行的函数
SQL注入
SQL注入因为要操作数据库,所以一般会查找SQL语句关键字:insert、delect、update、select,查看传递的变量参数是否用户可控制,有无做过安全处理。
防范方法:
使用参数化查询
XPath注入
Xpath用于操作XML,我们通过搜索Xpath来分析,提交给<font face='Arial,sans-serif''>xpath</font>
函数的参数是否有经过安全处理
防范方法:
对于数据进行精确匹配
HTTP响应拆分
PHP中可导致HTTP响应拆分的情况为:使用header函数和使用$_server变量。
注意PHP的高版本会禁止HTTP表头中出现换行字符,这类可以直接跳过本测试。
防范方法:
- 精确匹配输入数据
- 金策输入中如果有\r或者\n直接拒绝
文件管理
PHP的用于文件管理的函数,如果输入变量可由用户提交,程序中也没有做数据验证,可能成为高危漏洞。我们应该在程序中搜索如下函数:copy 、rmdir、unlink、delete、fwrite、chmod、fgetc、fgetss 、file、file_get_contents、fread、readfile、ftruncate、file_put_contents、fputcsv、fputs,通常PHP中每一个文件操作函数都可能是危险的。
防范方法:
- 对提交数据进行严格匹配
- 限定文件可操作的目录
文件上传
PHP文件上传通常会使用move_upload_file,也可以找到文件上传的程序进行具体分析。
防范方法:
- 使用白名单方式检测文件后缀
- 上传之后按时间算法生成文件名
- 上传目录脚本文件不可执行
- 注意%00截断
变量覆盖
PHP变量覆盖会出现在下面几种情况:
1、遍历初始化变量
例如:
foreach($_GET as $key=>$values)
$$key=$value;
2、函数覆盖变量:parse_str、mb_parse_str、import_request_variables
3、Register_globals=ON时,GET方式提交变量会直接覆盖
防范方法:
- 设置Register_globals=OFF
- 不要使用这些函数来获取变量
动态函数
当使用动态函数时,如果用户对变量可控,则可导致攻击者执行任意函数。
例如:
<?php $myfunc=$_GET['myfunc' font>];
$myfunc();
?>
防御方法:
不要使用这种函数