PHP项目安全:使用PHP的访问限制

  • A+
所属分类:安全开发

转自:计算机与网络安全

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()访问远程数据。

PHP项目安全:使用PHP的访问限制

图1  PHP远程访问开启


下面是示例代码,通过传递统一资源定位符(Uniform Resource Locators,URL)打开远程地址。


<?php

$url=$_GET['url'];

$result=file_get_contents($url);

echo$result;


可以通过传递URL参数来间接地访问其他网站,如输入百度的地址来执行程序。从图2的执行结果中可以看到,file_get_contents成功地远程获取了百度首页的内容。

PHP项目安全:使用PHP的访问限制

图2  远程访问开启执行结果


很多研发人员使用这些功能,通过FTP或是HTTP来远程获得数据。然而,这种方法在基于PHP应用程序中会造成一个很大的漏洞。由于部分PHP研发人员缺乏安全认知,在处理用户提交的数据时,没有对恶意用户所提交的数据进行过滤或转码,错误地访问了恶意用户提交的数据中包含的恶意链接,从而将该链接中的攻击代码加载到页面中,导致产生安全漏洞。要解决此问题,需要禁用过程访问。


allow_url_fopen=off ; 禁用PHP远程URL访问

allow_url_include=off ; 禁用远程INCLUDE文件包含


把allow_url_fopen的值更改为Off将其禁用,再次执行代码,可以看到PHP禁止了远程访问,出现图3所示“用户远程访问已经关闭”的提示。

PHP项目安全:使用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所列是一些建议禁用的函数,要尽量避免使用这些函数,防止给系统留下隐患。

PHP项目安全:使用PHP的访问限制

表1  建议禁用的函数


团队网络安全技术方向公众号,给个关注PHP项目安全:使用PHP的访问限制

原文始发于微信公众号(LemonSec):PHP项目安全:使用PHP的访问限制

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: