## 防止SQL注入,进行数据过滤 在ThinkPHP5中提供了许多数据输入过滤方法,例如 ``` //强制转换为Email格式 $this->request->post('email','',FILTER_VALIDATE_EMAIL); $this->request->post('email','','email'); //强制转换为数字 $this->request->post('id/d','0'); ``` 常用的修饰符如下 | 修饰符 | 作用 | | :-- | :-- | | s | 强制转换为字符串类型 | | d | 强制转换为整型类型 | | b | 强制转换为布尔类型 | | a | 强制转换为数组类型 | | f | 强制转换为浮点类型 | ## 防止XSS跨站注入 解决防范XSS跨站注入的首先是按照上方的SQL注入做好请求数据过滤,其次是做好数据输出时的编码,我们在视图模板中编写代码时,可以通过添加`htmlentities`对HTML代码做实体编码,例如 ``` <input type="text" name="username" value="{$username|htmlentities}" /> ``` 千万不要直接使用以下的代码,以下代码都是非常不安全的 ``` <input type="text" name="username" value="{$Think.get.username}" /> 或 <input type="text" name="username" value="{$_GET['username']}" /> ``` ## CSRF跨站请求 CSRF全称为`cross site request forgery`,中文意思为:`跨站点伪装请求`。 >跨站点请求的原理就是`用户A`在`站点1`发布上传粘贴了一个`站点2`的URL,`用户B`不明就里的点击了`站点2`的URL,而这个URL因为是伪装请求`站点1`修改密码(其它危险请求)的操作。此时`用户A`就已经获取了`用户B`的账户信息。 例如我们常常在编写表单提交的时候都是如下的写法 ``` <form action=""> <input type="password" name="newpassword" /> <input type="submit" /> </form> ``` 以上的写法很容易产生CSRF跨站点伪装请求。 在ThinkPHP5可以很方便的使用`token`的方式来防范这种威胁,比如我们将上面的代码改写为 ``` <form action=""> {:token()} <input type="password" name="newpassword" /> <input type="submit" /> </form> ``` 我们添加了一个`{:token()}`,由于这个token是我们服务端动态输出的,伪装者的服务器没法获取该值,此时我们再做好服务端验证这个`token`是否有效即可,常用的方法如下 ``` $token = $this->request->post('__token__'); //验证Token if (!$token || !\think\Validate::is($token, "token", ['__token__' => $token])) { $this->error("请勿非常请求"); } ``` 更多Token表单令牌的使用方法可以参考ThinkPHP5官方文档:[https://www.kancloud.cn/manual/thinkphp5/193918](https://www.kancloud.cn/manual/thinkphp5/193918) ## 服务器安全 ### 目录安全 目录安全在是经常容易生产问题的一个环节,很多时候我们都会忽略或忘记进行站点目录安全的配置。 我们建议在生产环境只开放`uploads`和`runtime`目录的读写权限,其次还需要关闭`uploads`目录执行PHP的权限,因为很多时候用户上传恶意脚本,而服务端`uploads`目录又未屏蔽PHP,导致用户数据泄漏丢失。 通常情况在生产环境下建议使用 ``` chown www:www /var/www/yoursite -R chmod 655 /var/www/yoursite -R chmod u+w /var/www/yoursite/runtime -R chmod u+w /var/www/yoursite/public/uploads -R ``` 通过以上的配置还不够,我们还需要继续对服务器做WEB配置以限制PHP脚本的运行 --- ### WEB配置 Nginx可以通过以下配置禁止PHP脚本执行 ``` location ~ ^/(uploads|assets)/.*\.(php|php5|jsp)$ { deny all; } ``` Apache可以通过在`.htaccess`中配置来禁用PHP脚本执行 ``` RewriteEngine on RewriteCond % !^$ RewriteRule uploads/(.*).(php)$ – [F] ``` 或使用 ``` <Directory "/www/yoursite/public/uploads"> <Files ~ ".php"> Order allow,deny Deny from all </Files> </Directory> ``` 其次在新增网站配置时务必绑定`public`目录为运行目录,同时启用`open_basedir`限制只允许FastAdmin的根目录,例如:`fastcgi_param PHP_VALUE "open_basedir=/var/www/fastadmin/:/tmp/:/proc/";` 通常也建议修改`php.ini`,禁用不安全的函数,配置如`disable_functions = passthru,exec,system,chroot,chgrp,chown,shell_exec,proc_open,proc_get_status,popen,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,`