Php安全规范

 

一.基本准则

    1. 所有的用户输入都是有害的,对所有从客户端传入的数据都不信任, 需要做判断和过滤(类型,长度,格式,范围),否则可能会受到SQL Injection、XSS等攻击。比如:$_GET, $_POST, $_COOKIE, $_FILES, $REQUEST等。 直接使用将可能存在被注入的危险。
    1. 用户的相关输入涉及数据库操作时需要对输入做专门的转换。例如: 数据库操作中数字型的需要做intval转换,字符串类型的需要通过mysql_real_escape_string过滤。
    1. 用户上传的文件的文件名必须随机重新命名,并限制其后缀,大小,类型,并以明确的后缀结束。
    1. 数据库操作必须使用安全数据库操作类.不使用安全数据库操作类的,使用Intval对整数型参数过滤,使用mysql_real_escape_string对字符串型进行过滤,并要配合mysql_set_charset设置当前字符集进行使用。PHP版本小于5.0.5的,须使用SET character_set_connection=字符集, character_set_results=字符集, character_set_client=binary; 这三句语句替代mysql_set_charset进行数据库字符集设置。在能用PDO的情况下,最好用PDO的预编译功能。
    1. 最好别使用PHP调用shell,若实在要调用shell命令时,输入参数作为system,exec,passthru等任何命令执行函数的参数时,要使用escapeshellarg函数进行过滤。(escapeshellcmd在某些条件下会存在漏洞,因此强烈推荐使用escapeshellarg) 。
    1. 输入参数作为php文件内容时,要使用var_export进行数据导出。字符串尽量用’ ‘而不是” “进行引用,一个是效率问题,一个是安全问题。
    1. 输出到网页中的变量要用htmlspecialchars 处理转义 防止xss攻击。
    1. 若有输入变量带到网址跳转中去,必须校验域名地址,防止通过URL被篡改,从当前网站跳转到欺诈网站,产生钓鱼攻击。
    1. 一些其它数据来源:比如导入excel数据,在进入库或者查询时。必须进行转义处理。
    1. 对外提供API接口的,数据传输过程中建议使用rsa+aes 相结合的方式来做加密处理,防止数据传输过程中被嗅探和篡改.
    1. 入库中存放密码不能明文,用户密码不能用纯md5加密 应该用md5+salt等
    1. 在表单提交中,最好加入token机制,以防CSRF攻击。
  1. 若文件包含了一个用户输入变量,请校验后缀,路径等信息,过滤一些跨目录符号。如:../ .. .. 等 防止文件遍历。

二.安全配置

    1. magic_quotes_gpc = On 注:此配置项在php5.4中已经移除。自动把用户提交的变量进行转换,比如把 ‘ 转为 ’ 等,相当于php中的addslashes()函数的处理。这对防止sql注射有重大作用。
    1. register_globals=off 注:register_globals允许php将$_GET,$_POST,$_COOKIE等变量里的内容自动注册为全局变量,如果程序里的某些变量没有经过初始化而直接使用将导致安全问题。
    1. expose_php=off 注:避免PHP版本信息暴露。
    1. display_errors = Off 注:页面不显示错误显示
    1. Safe_mode=on 注:启用安全模式
    1. disable_functions=exec,passthru,popen,proc_open,shell_exec,system,phpinfo, assert 注:禁用一些危险函数,
    1. allow_url_fopen = Off allow_url_include = Off 注:防止远程包含漏洞。
    1. session.cookie_httponly = 1 注:防止在xss漏洞中暴露cookies
  1. 设置好合适的 open_basedir  防止一个网站被入侵,同服所有网站被沦陷风险的跨站点攻击。

三.其它容易被忽略的地方

  1. 注意php各版本之间的区别 比如:php5.4 php5.5中 $_REQUEST 默认只包含 $_GET $_POST 不包含$_COOKIES

     public function dispose_request()
         {
             $_POST = daddslashes($_POST);
             $_GET  = daddslashes($_GET);
             $_REQUEST = daddslashes($_REQUEST);
     }
     上面的代码如果是在PHP5。3以上的环境中运行  $_COOKIES变量是没有经过转义的。
    
  2. 通用过滤转义函数在过滤数组时,别忘记对$key过滤

     function daddslashes($string, $force = 0)
     {
         if (!get_magic_quotes_gpc() || $force)
         {
             if (is_array($string))
             {
                 foreach ($string as $key => $val)
                 {
                     $string[$key] = daddslashes($val, $force);
                 }
             }
             else
             {
                 $string = addslashes($string);
             }
         }
         return $string;
     }
       $test[“username’a”]=”admin’a” //只转义了数组对应的value  key没有转义
       $test=daddslashes($test);
    
  3. 在用preg_replace 中,慎用e 参数

       function dunserialize($string)
       {
           return unserialize(preg_replace('!s:(d+):"(.*?)";!se', '"s:".strlen("$2").":"$2";"', $string));
       }
       $str='s:123:"${phpinfo()}";';
       dunserialize($str);   //程序最终会执行php代码,产生代码执行漏洞
    
        其它会产生类似代码执行漏洞的函数还有:
         eval create_function call_user_func call_user_func_array assert  等 在使用这些函数时务必注意参数的合法性。
    
  4. parse_str使用过程中注意变量覆盖和注入漏洞

     parse_str('a=%27');
     php<=5.3  $a=’
     Php>5.3  $a=’
    
  5. 在要对浏览器标识入库时,必须做转义处理。

     $agent = addslashes($_SERVER['HTTP_USER_AGENT']);
    
  6. 在取客户端IP中。若取到了$_SERVER[‘HTTP_X_FORWARDED_FOR’]这段。请校验该字段的值是否为IP格式。因为这字段内容可随意伪造。
原文地址:https://www.cnblogs.com/hellohell/p/6114551.html