赞
踩
PHP可以直接访问本地服务器路径以及在服务器上执行脚本文件。合理地限制PHP的访问范围,可以有效地制止恶意用户对服务器的攻击。
1、文件系统限制
在PHP中可以通过配置open_basedir来限制PHP访问文件系统的位置,将PHP执行权限限制在特定目录下。当PHP访问服务器的文件系统时,这个设置的位置将被检查。当访问的文件在目录之外时,PHP将拒绝访问。
开启open_basedir可以有效地对抗文件包含、目录遍历等攻击,防止攻击者访问非授权目录文件。
open_basedir=/home/web/php/
; 限定PHP的访问目录为/home/web/php/
为此选项设置一个值,需要注意的是,如果设置的值是一个指定的目录,则需要在目录最后加上一个“/”,否则会被认为是目录的前缀。
限制访问示例如下。
<?php
echofile_get_contents("/etc/passwd");
// 读取非授权路径
?>
运行结果如下所示。
Warning:file_get_contents():open_basedir restriction in effect.File(/etc/passwd) is not within the allowed path(s):(/home/web/php/) in /home/web/php/index.php on line 3
如果使用函数file_get_contents()访问系统文件路径/etc/passwd,由于该目录不在/home/web/php/中,因此PHP将禁止访问并抛出异常,从而有效地防止目录被非法访问。
2、远程访问限制
图1所示的PHP配置,当PHP的远程访问选项allow_url_fopen开启时,允许PHP系统拥有从远程检索数据的功能,如通过PHP来访问远程FTP或Web,使用file_get_contents()访问远程数据。
下面是示例代码,通过传递统一资源定位符(Uniform Resource Locators,URL)打开远程地址。
<?php
$url=$_GET["url"];
$result=file_get_contents($url);
echo$result;
可以通过传递URL参数来间接地访问其他网站,如输入百度的地址来执行程序。从图2的执行结果中可以看到,file_get_contents成功地远程获取了百度首页的内容。
很多研发人员使用这些功能,通过FTP或是HTTP来远程获得数据。然而,这种方法在基于PHP应用程序中会造成一个很大的漏洞。由于部分PHP研发人员缺乏安全认知,在处理用户提交的数据时,没有对恶意用户所提交的数据进行过滤或转码,错误地访问了恶意用户提交的数据中包含的恶意链接,从而将该链接中的攻击代码加载到页面中,导致产生安全漏洞。要解决此问题,需要禁用过程访问。
allow_url_fopen=off ; 禁用PHP远程URL访问
allow_url_include=off ; 禁用远程INCLUDE文件包含
把allow_url_fopen的值更改为Off将其禁用,再次执行代码,可以看到PHP禁止了远程访问,出现图3所示“用户远程访问已经关闭”的提示。
3、开启安全模式
PHP的安全模式是为试图解决共享服务器(shared-server)的安全问题而设立的。开启之后,主要会对系统操作、文件、权限设置等方法产生影响,减少被攻击者植入webshell所带来的某些安全问题,从而在一定程度上避免一些未知的攻击。
可以通过在PHP配置文件中修改safe_mode的值为On来开启PHP安全模式。
safe_mode=on ; 开启安全模式
safe_mode_gid=off
启动safe_mode时,会对许多PHP函数进行限制,特别是与系统相关的文件打开、命令执行等函数。所有操作文件的函数将只能操作与脚本UID相同的文件。
如果要将其放宽到GID比较,则设置safe_mode_gid=On可以考虑只比较文件的GID。
设置safe_mode以后,所有命令执行的函数将被限制只能执行php.ini里safe_mode_exec_dir指定目录里的程序,例如使用shell_exec()、exec()等函数执行命令的方式会被禁止。如果确实需要调用其他程序,可以在php.ini中进行如下设置。
safe_mode_exec_dir = /usr/local/php/exec
在PHP配置文件中设置选项safe_mode_include_dir,然后复制可执行程序到/usr/local/php/exec目录,这个目录中的可执行程序不受UID/GID检查约束,PHP脚本就可以用shell.exec()、exec()、stustem()等函数来执行这些程序。而且该目录里的Shell脚本还可以调用其他目录里的系统命令。
从PHP 4.2.0版本开始,safe_mode_exec_dir参数可以接受以目录格式字符串为前缀的匹配方式。指定的限制实际上是一个前缀,而非一个目录名称。例如,在系统中如果定义“safe_mode_include_dir =/dir/incl”,字符串将允许访问“/dir/include”和“/dir/inclouds等以“/dir/ind”开头的目录路径。如果希望将访问控制在一个指定的目录中,则应在结尾加上一个斜线。
safe_mode_include_dir = /dir/incl/
当启用安全模式时,可以通过PHP设置选项safe_mode_allowed_env_vars来设置哪些系统环境变量可以被修改,用户只能改变在这里提供的前缀的环境变量。默认情况下,用户只能设置以PHP_开头的环境变量(例如PHP_FOO = BAR)。
safe_mode_allowed_env_vars = PHP
注意,safe_mode_allowed_env_vars设置项为空,PHP将使用户可以修改任何环境变量。
safe_mode_protected_env_vars=string
PHP的safe_mode_protected_env_vars设置项,包含由一个逗号分隔的环境变量的列表,最终用户不能用putenv()来改变这些环境变量,甚至在safe_mode_allowed_env_vars中设置了允许修改时也不能改变这些变量。
虽然PHP的安全模式不是万能的,但还是强烈建议打开安全模式,这样能在一定程度上避免一些未知的攻击。不过在启用安全模式后会有很多限制,可能对应用带来影响,所以还需要通过调整代码和系统配置来综合考虑。
4、禁用危险函数
PHP配置文件中的disable_functions选项能够在PHP中禁用指定的函数。PHP中有很多危险的内置功能函数,如果使用不当,可能造成系统崩溃。禁用函数可能会为研发带来不便,但禁用的函数太少又可能增加研发人员写出不安全代码的概率,同时为攻击者非法获取服务器权限提供便利。
在PHP配置文件中添加需要禁用的函数可以有效地避免webshell,如下所示就是在PHP配置中添加了多个常用的禁用函数。
; http://php.net/disable-functions
disable_functions=phpinfo,eval,passthru,exec,system,chroot,scandir,chgrp,chown,shell_exec,proc_open,proc_get_status,ini_alter,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,popepassthru,stream_socket_server,fsocket,fsockopen
表1所列是一些建议禁用的函数,要尽量避免使用这些函数,防止给系统留下隐患。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。