PHP代码审计
2011 年 2 月 13 日
文档去年做的,按说应该更新了,写得不咋好,有些没写全,参考了很多文档。
话说owasp codereview,也该出2.0了。
牛们路过,给提点建议。
目录
1. 概述 3
2. 输入验证和输出显示 3
2.1 命令注入 4
2.2 跨站脚本 4
2.3 文件包含 5
2.4 代码注入 5
2.5 SQL注入 6
2.6 XPath注入 6
2.7 HTTP响应拆分 6
2.8 文件管理 6
2.9 文件上传 7
2.10 变量覆盖 7
2.11 动态函数 7
3. 会话安全 8
3.1 HTTPOnly设置 8
3.2 domain设置 8
3.3 path设置 8
3.4 cookies持续时间 8
3.5 secure设置 8
3.6 session固定 9
3.7 CSRF 9
4. 加密 9
4.1 明文存储密码 9
4.2 密码弱加密 9
4.3 密码存储在攻击者能访问到的文件 9
5. 认证和授权 10
5.1 用户认证 10
5.2 函数或文件的未认证调用 10
5.3 密码硬编码 10
6. 随机函数 10
6.1 rand() 10
6.2 mt_srand()和mt_rand() 11
7. 特殊字符和多字节编码 11
7.1 多字节编码 11
8. PHP危险函数 11
8.1 缓冲区溢出 11
8.2 session_destroy()删除文件漏洞 12
8.3 unset()-zend_hash_del_key_or_index漏洞 12
9. 信息泄露 13
9.1 phpinfo 13
10. PHP环境 13
10.1 open_basedir设置 13
10.2 allow_url_fopen设置 13
10.3 allow_url_include设置 13
10.4 safe_mode_exec_dir设置 14
10.5 magic_quote_gpc设置 14
10.6 register_globals设置 14
10.7 safe_mode设置 14
10.8 session_use_trans_sid设置 14
10.9 display_errors设置 14
10.10 expose_php设置 14
概述
代码审核,是对应用程序源代码进行系统性检查的工作。它的目的是为了找到并且修复应用程序在开发阶段存在的一些漏洞或者程序逻辑错误,避免程序漏洞被非法利用给企业带来不必要的风险。
代码审核不是简单的检查代码,审核代码的原因是确保代码能安全的做到对信息和资源进行足够的保护,所以熟悉整个应用程序的业务流程对于控制潜在的风险是非常重要的。审核人员可以使用类似下面的问题对开发者进行访谈,来收集应用程序信息。
应用程序中包含什么类型的敏感信息,应用程序怎么保护这些信息的?
应用程序是对内提供服务,还是对外?哪些人会使用,他们都是可信用户么?
应用程序部署在哪里?
应用程序对于企业的重要性?
最好的方式是做一个checklist,让开发人员填写。Checklist能比较直观的反映应用程序的信息和开发人员所做的编码安全,它应该涵盖可能存在严重漏洞的模块,例如:数据验证、身份认证、会话管理、授权、加密、错误处理、日志、安全配置、网络架构。
输入验证和输出显示
大多数漏洞的形成原因主要都是未对输入数据进行安全验证或对输出数据未经过安全处理,比较严格的数据验证方式为:
对数据进行精确匹配
接受白名单的数据
拒绝黑名单的数据
对匹配黑名单的数据进行编码
在PHP中可由用户输入的变量列表如下:
$_SERVER
$_GET
$_POST
$_COOKIE
$_REQUEST
$_FILES
$_ENV
$_HTTP_COOKIE_VARS
$_HTTP_ENV_VARS
$_HTTP_GET_VARS
$_HTTP_POST_FILES
$_HTTP_POST_VARS
$_HTTP_SERVER_VARS
我们应该对这些输入变量进行检查
命令注入
PHP执行系统命令可以使用以下几个函数:system、exec、passthru、“、shell_exec、popen、proc_open、pcntl_exec
我们通过在全部程序文件中搜索这些函数,确定函数的参数是否会因为外部提交而改变,检查这些参数是否有经过安全处理。
防范方法:
使用自定义函数或函数库来替代外部命令的功能
使用escapeshellarg函数来处理命令参数
使用safe_mode_exec_dir指定可执行文件的路径
跨站脚本
反射型跨站常常出现在用户提交的变量接受以后经过处理,直接输出显示给客户端;存储型跨站常常出现在用户提交的变量接受过经过处理后,存储在数据库里,然后又从数据库中读取到此信息输出到客户端。输出函数经常使用:echo、print、printf、vprintf、<%=$test%>
对于反射型跨站,因为是立即输出显示给客户端,所以应该在当前的php页面检查变量被客户提交之后有无立即显示,在这个过程中变量是否有经过安全检查。
对于存储型跨站,检查变量在输入后入库,又输出显示的这个过程中,变量是否有经过安全检查。
防范方法:
如果输入数据只包含字母和数字,那么任何特殊字符都应当阻止
对输入的数据经行严格匹配,比如邮件格式,用户名只包含英文或者中文、下划线、连字符
对输出进行HTML编码,编码规范
< <
> >
( (
) )
# #
& &
原文转自:http://www.sectop.com/?p=111