PHP安全编码规范之安全配置篇
因为配置不当引发的安全问题是屡见不鲜的,通过一系列的安全配置,可以很好的解决一些安全隐患,从而为系统增加安全系数。但是在开发过程中,因为需求的改变和编程的习惯可能会更改一些配置同时带来安全隐患。在这种情况下,需要更加的了解配置带来的安全隐患,也就是漏洞的产生原理。同时需要了解在打开一些配置安全隐患之后,该如何通过一些其他手段解决安全问题是我们重点需要讨论的问题。
0×01注册全局变量带来的安全隐患
register_globals这个是开启全局注册变量功能,为On是开启,Off是关闭。在开启后带来的安全隐患是巨大的,所以建议关闭。如果在需求上需要开启,在02里会有具体介绍该如何防御。
配置规范:register_globals要设置为off,在php4.2.0后默认为off,如果为on,需要为每个变量初始化
功能描述:get,post,cookie等变量直接被注册为全局变量,比如表单的username,程序中使用$username就能获取到值,不需$_POST来获取值
安全隐患样例:
这里如果没有通过cooke认证,那$authorized将一直为假,就无法被认证,但是如果register_globals为on,那么我们在url里可以修改get参数让$authorized注册为全局变量,并修改它的值为真,比如http://xxx/test.php?authorized=1,这样就绕过了认证。
0×02初始化变量和配置预警提高安全系数
如果有需求要开启注册全局变量,那我们该如何防御呢?这里我们介绍两个办法,一个是初始化变量,和配置最高预警信息,下面让我们看看具体如何操作。在这里我们初始化了$authorized的值为假,即使传入了真也不会改变
比如:
所以我们只要初始化$authorized的值,就不会出现绕过的问题,但是有的时候会忘记初始化变量,没关系,可以配置预警模式,如果有未初始化的,就会预警,可以在php.ini中设置 error_reporting 设置为 E_ALL|E_STRICT最高级别,这样如果哪个变量未初始化,报错就会预警。
0×03 配置不显示错误信息,保存错误信息到本地
黑客在渗透过程中,因为错误信息的暴露,给黑客提供了很大的利用便利条件,所以在开发过程中,我们可以为了编程的方便,需要开启错误信息提示到浏览器,但是在程序上线后,我们一定要关闭错误信息提示,这里提供一种一举两得的方式,关闭浏览器显示错误提示,记录错误提示到本地日志中。这些设置可以在php.ini中设置,也可以在php程序中设置。
0×04 权限问题-能不给的权限不要给
关于权限问题始终是一个容易被忽略的问题,程序员往往在乎程序功能上是否实现了,的确容易在功能上过大的给予一些权限照成一些安全隐患。比如我们在上传过程中,可能只需要写权限和执行权限,但是我们又多给了个读权限。即便我们做了过滤,即便我们做了混淆,但是安全不是绝对的,一个环节的疏忽就容易照成不可挽回的损失。下面让我们看一个案例
案例分析:
这是一个上传功能,这里的功能需求只需要写权限和执行权限,可以看到,只用了getimagesize做了图片认证,这里只需要改下文件类型就可以简单绕过上传一个php的木马,但是同时对上传的文件名重新命名成了随机名,所以攻击者不知道源码很难逆向文件名来解析php木马。
但是我们又多给了读取权限,会有什么样的安全隐患呢?比如这个程序里有这样一个功能
这里是一个ping的功能,即使做了一些过滤,但是因为过滤不全,没有过滤&,{,}等符号,
可以这样绕过从这张图片可以看到,我们本来不需要读权限,但是因为给了读权限,让攻击者在这里可以读到文件名甚至其他一些操作,从这两点的结合,攻击者可以很轻易获取到程序的权限从而带来很严重的信息泄露等问题。所以回到我们讨论的问题,最小权限问题,这里在需求上完全不需要读权限,但是因为读权限的开启,照成了严重的损失,所以,能不给的权限不要给,给过的权限,一定要做好过滤等防御措施。
0×05 allow_url_include 和allow_url_fopen
这两个功能开启后带来的安全隐患也是巨大的,会带来远程命令包含命令执行漏洞。所以建议关闭,如果有需求,需要对外来变量做过滤。至于如何过滤,具体情况具体分析。
配置规范:都关闭,都开启可以加载远程恶意文件到本地写木马,也就是远程文件包含漏洞
配置功能:allow_url_include 允许加载远程php文件,allow_url_fopen允许加载远程本地写文件,比如fopen,file_put_contents
案例分析:如果这两个功能都开启
这样攻击者就可以成功写入恶意木马程序到你的服务器中,如果 allow_url_fopen 为off,就无法写入,但是可以执行其他命令即使关闭了这两个配置选项,也不建议把外来变量直接放入包含函数里,因为同样会引起本地包含漏洞,可以加载本地任意类型文件,如果攻击者结合上传漏洞上传info.png图片木马,一样会引起严重的损失。利用方式类似1.php?file=./info.png
0×06 magic_quotes_gpc, magic_quotes_runtime
这两个都是魔术引号,都能自动过滤,但各有不同。开启后,系统会自动过滤外来变量减少一些安全隐患和编程便利问题:
1.magic_quotes_gpc代表get,post,cookie变量的过滤,过滤有单引号,双引号,反斜杠,空字符,都用反斜杠转义,但是gpc过滤还是不完整的,比如php5中$_SERVER变量不会过滤,如果程序中,把client-ip,referer存到数据库中就能引发sql注入。
2.magic_quotes_runtime是对文件或者数据库中取出的数据过滤,能很好的解决二次注入漏洞。
3.然后说说带来的问题,用自动过滤自然省事,但是同时也带来了一些性能损耗,同时在做一些逻辑判断时候,会出现问题,需要把反斜杠去掉再处理,用strislashes函数去掉,这就比较麻烦,所以最好做全局过滤框架来过滤。
0×07 safe_mode
这是php的安全模式,开启后会提升系统的安全系数,但是在开发会带来一些不变和步骤。配置规范:开启安全模式,会对程序带来一定安全性,不过同时也会限制一些功能的使用,如何取舍,还是要具体分析。
功能描述:限制函数使用权限和操作目录文件权限等功能。检验用户是否有操作文件权限。比如:如果要在安全模式下包含某些公共文件,可以选用它的子配置 safe_mode_include_dir = D:/phpstudy/www/include/
0×08 open_basedir
这个是目录权限的控制,开启可以增加安全系数,但是会影响到性能,因为每次有对目录操作权限的地方都会判断这个地方,如何取舍需要具体分析。open_basedir = /var/www/a/:/var/www/b/a中
php程序和b中php程序不能相互访问
linux用冒号分割,windows用分号分割
0×09 disable_functions
禁止一些敏感函数使用也能带来很大的安全保障,但是也同样影响了一些功能使用,具体使用具体分析安全防范禁止命令执行函数
disable_functions = system,passthru,exec,shell_exec,popen,pcntl_exec,proc_open
禁止文件操作函数disable_functions=chdir,chroot,dir,getcwd,opendir,readdir,scandir,fopen,unlink,delete,copy,mkdir,rmdir,rename,file,file_get_contents,fputs,fwrite,chgrp,chmod,chow
0×10 expose_php
隐藏php版本信息,使攻击者在信息收集时候无法判断程序版本,增加防御系数,建议为off。expose_php =off 为开启
0×11 display_startup_errors
这个可以跟display_errors做比较,区别是这个是php程序启动时产生的错误,和display_errors是不一样的,也建议关闭,增加防御系数。
0×12 补充-apache服务器的安全配置
既然说到配置,那这里也要注意一个容易暴露信息的配置,让我们来看看apche配置文件下httpd.conf文件的一个配置
这个是我的phpstudy安装后自动配置的,这里有一个很不安全的两个配置,一个是Indexes,一个是ExecCGI。Indexes会在找不到index文件时候列出文件目录,如果程序中有mysql.inc等文件的话,那就直接暴露给了攻击者,让攻击者很容易拿到系统权限。ExecCGI就是允许服务器启用cgi功能,cgi是common gataway interface,简单解释就是比如脚本语言支撑服务器和用户请求的接口,多用来处理表单等信息,但是bash漏洞的影响,导致很多服务器因为开启cgi而沦陷,所以没有这个需求最好不要开启。加号是追加开启,所以这里可以直接把加号改成减号取消掉这两个功能, FollowSymLinks 是重定向用的,程序配置等有重定向的地方会自动重定向,不需要这个功能也最好关闭。 DocumentRoot 是配置web根目录,Directory控制目录权限。
总结:首先我们都清楚安全不是绝对的,不是仅仅配置了这些文件就能保证你的程序绝对安全。但是,通过这一系列的配置,至少阻挡很多攻击方式,这一篇是对配置文件的一个总结和概括,下一篇会对语法函数使用的安全问题进行展开详细介绍,让我们进一步使我们的程序变得更加的安全