1 Star 0 Fork 0

零壹工作室 / tp6start

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
02.09安全规范.md 5.60 KB
一键复制 编辑 原始数据 按行查看 历史
守信哥 提交于 2020-02-04 00:37 . 完成格式调整

请求变量过滤

永远不要相信用户的输入,这是一句至理名言。尽可能的过滤请求变量能有效防范大部分的漏洞和隐患。

框架建议的获取请求变量的方法是Request类的param方法(如非必要不要再使用get或者post方法获取,更不要使用原生的$_GET/$_POST等方法获取)。

public function index(Request $request)
{
    $name = $request->param('name');

    // 在这里可以根据你的业务需求进行更严谨的过滤
    // 例如 $name = $request->param('name','','htmlentities,strtolower');
    // 或者使用验证器进行专门的验证
}

对于有明确类型的请求变量,可以在使用param方法的时候使用类型强制转换,例如:

public function index(Request $request)
{
    // 强制转换字符串数据
    $name = $request->param('name/s');

    // 强制转换整型数据
    $name = $request->param('id/d');

    // 强制转换浮点型数据
    $name = $request->param('score/f');
}

或者直接使用方法参数获取请求变量

public function index(string $name)
{
    // 在这里可以根据你的业务需求进行更严谨的过滤
    // 或者使用验证器进行专门的验证
}

如果你需要对所有数据进行处理,可以设置全局的过滤方法。对不同的应用需求设置default_filter过滤规则(默认没有任何过滤规则),常见的安全过滤函数包括stripslasheshtmlentitieshtmlspecialcharsstrip_tags等,请根据业务场景选择最合适的过滤方法。

如果需要获取多个数据,建议使用only方法指定需要获取的变量名称,避免有些不怀好意的数据提交导致权限问题。

public function index(Request $request)
{
    // 指定表单数据名称
    $data = $request->only(['name','title']);
}

当你使用数据库或者模型操作写入数据的时候,也可以指定字段,避免非法和不希望的字段写入数据库。

// 模型
User::allowField(['name','title'])
    ->save($data);

// 数据库
Db::name('user')
    ->field(['name','title'])
    ->insert($data);

模型还有一个只读字段功能能避免你的数据受到外部的修改。

上传检测

网站的上传功能也是一个非常容易被攻击的入口,所以对上传功能的安全检查是尤其必要的。

系统的验证类提供了文件上传的安全支持,包括对文件后缀、文件类型、文件大小以及上传图片文件的合法性检查,确保你已经在上传操作中启用了这些合法性检查。

SQL注入

ThinkPHP的查询统一使用了PDOprepare预查询和参数绑定机制,能有效的避免SQL注入的发生。但不代表绝对安全,如果你缺乏良好的代码规范,仍然有可能被利用。

一个最简单的原则就是不要让用户决定你的查询条件(或者字段排序)和控制你的查询数据。

对于一些字符串的查询条件(包括原生查询)或者特殊的查询(包括ORDER部分),需要手动进行参数绑定。

// 错误的
Db::query("select * from think_user where id=$id AND status=$statis");
// 正确的
Db::query("select * from think_user where id=? AND status=?", [ $id, $status]);
// 正确的
Db::execute("update think_user set name=:name where status=:status", [
    'name'     => 'thinkphp', 
    'status'   => 1
]);

对于使用了whereExpwhereRaw方式的查询,你也需要使用参数绑定。

Db::name('user')
    ->whereRaw('id > ? AND status = ?',[10, 1])
    ->select();

使用验证器

对于大量的表单需要验证的情况,建议使用验证器功能统一进行数据的合规验证。验证器的验证操作应该在控制器或者路由阶段使用validate方法进行处理,模型的数据验证功能新版已经取消不再建议使用,模型和数据库操作的时候应该传入经过安全处理过的数据。

XSS攻击

跨站脚本攻击(cross-site scripting,简称XSS),XSS是一种在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。

在渲染输出的页面中,要对一些数据进行安全处理,防止被恶意利用造成XSS攻击,如果是5.1版本的话,所有的输出都已经经过了htmlentities转义输出,确保安全。如果是5.0版本的话,你可以自定义一个xss过滤函数,在模板文件中对一些关键内容变量进行函数处理。

CSRF

CSRF 跨站请求伪造是 Web 应用中最常见的安全威胁之一,攻击者伪造目标用户的HTTP请求,然后此请求发送到有CSRF漏洞的网站,网站执行此请求后,引发跨站请求伪造攻击。攻击者利用隐蔽的HTTP连接,让目标用户在不注意的情况下单击这个链接,由于是用户自己点击的,而他又是合法用户拥有合法权限,所以目标用户能够在网站内执行特定的HTTP链接,从而达到攻击者的目的。

开启表单令牌验证,尽量开启强制路由并严格规范每个URL请求,定义单独的MISS路由规则。

遵循请求类型的使用规范并做好权限验证,删除操作必须使用DELETE请求,数据更改操作必须使用POSTPUT或者PATCH请求方法,GET请求不应该更改任何数据。

写更健壮的代码

安全问题不容忽视,参考官方发布的安全规范指引,提前做好安全防范,让你的项目更健壮。同时也要关注官方的开发者周刊和微信公众号,及时获取官方的安全更新通告。

1
https://gitee.com/wgsuxin/tp6start.git
git@gitee.com:wgsuxin/tp6start.git
wgsuxin
tp6start
tp6start
master

搜索帮助