WAF

WAF

waf 使用安全团队提供的waf解决方案。

目前集成需要构建在镜像,后需会以前置为waf服务。

代码中的安全防御

首先,要了解常见的安全攻击方式和防御手段。之后再根据我们的业务形态和编码规范来确定防御手段。

常见攻击方式

xss、csrf、Injection注入攻击(代码执行,sql注入)、越权、暴力破解、Include文件包含、逻辑漏洞

XSS

跨站脚本攻击(cross-site scripting,简称 XSS),具体危害体现在黑客能控制你网站页面,包括使用 JS 盗取 Cookie 等,关于 XSS 的介绍请前往 IBM 文档库:跨站点脚本攻击深入解析

防御手段

我们的安全策略

不要相信任何用户的输入!
不要相信任何用户的输入!
不要相信任何用户的输入!

策略1:严格的用户输入校验

为每个controller指定对应的Request对象,在Request中完成用户输入的额校验。

使用白名单(用户输入是固定模式)的方式,比如用户名只能使用数字字母,那么可以使用函数ctype_alnum判断;比如手机号只能使用数字,那么可以使用函数is_numeric判断。

对用户输入使用函数 htmlentities或者htmlspecialchars进行处理,输入url不允许传入非http协议,如果是固定URL,采用白名单的方式或这存储在库中通过标识访问。

策略2:打开csrf防御中间件,且不允许设置白名单

CSRF 跨站请求伪造是 Web 应用中最常见的安全威胁之一,具体请见 Wiki - 跨站请求伪造 或者 Web 应用程序常见漏洞 CSRF 的入侵检测与防范

Laravel 默认对所有『非幂等的请求』强制使用 VerifyCsrfToken 中间件防护,需要开发者做的,是区分清楚什么时候该使用『非幂等的请求』。

幂等请求指的是:'HEAD', 'GET', 'OPTIONS',既无论你执行多少次重复的操作都不会给资源造成变更。

所有删除的动作,必须 使用 DELETE 作为请求方法;
所有对数据更新的动作,必须 使用 POST、PUT 或者 PATCH 请求方法。

策略3:开启用户访问频次限制中间件,按照业务设定频次

限流
Laravel 包含了一个 中间件 用于控制应用程序对路由的访问。 如果想要使用, 请将 throttle 中间件分配给一个路由或者一个路由组。throttle 中间件会接收两个参数,这两个参数决定了在给定的分钟数内可以进行的最大请求数。例如,让我们指定一个经过身份验证并且用户每分钟访问频率不超过 60 次的路由组:

Route::middleware('auth:api', 'throttle:60,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});

动态限流
你可以根据已验证的 User 模型的属性,指定动态请求的最大值。例如,如果你的 User 模型包含 rate_limit 属性,则可以将属性名称传递给 throttle 中间件,以便它用于计算最大请求数:

Route::middleware('auth:api', 'throttle:rate_limit,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});

独立访客和认证用户的限流
您可以为访客和经过身份验证的用户指定不同的访问控制。例如,可以为访客指定每分钟最多 10 次请求,为认证用户设置每分钟最多 60 次请求:

Route::middleware('throttle:10|60,1')->group(function () {
    //
});

您还可以将此功能与动态限流相结合。例如,如果 User 模型包含一个 rate_limit 属性,您可以将该属性的名称传递给 throttle 中间件,以便用于计算认证用户的最大请求数:

Route::middleware('auth:api', 'throttle:10|rate_limit,1')->group(function () {
    Route::get('/user', function () {
        //
    });
});

api middleware group
laravel中间件中api默认实现了限流,策略: throttle:60,1

// app/Http/Kernel.php
protected $middlewareGroups = [
    'api' => [s
        'throttle:60,1',
        'bindings',
    ],
];

protected $routeMiddleware = [
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class
];

策略4:引入并开启xss过滤中间件

默认情况下,在无法保证用户提交内容是 100% 安全的情况下,必须 使用 Blade 模板引擎的 {{ $content }} 语法会对用户内容进行转义。

Blade 的 {!! $content !!} 语法会直接对内容进行 非转义 输出,使用此语法时,必须 使用 HTMLPurifier for Laravel 5 来为用户输入内容进行过滤。使用方法参见: 使用 HTMLPurifier 来解决 Laravel 5 中的 XSS 跨站脚本攻击安全问题

方法一:安装 HTMLPurifier for Laravel 5

composer require mews/purifier

方法二:基于CI-的xxx组件

策略5:使用prepared防御SQL注入

Laravel 的 查询构造器Eloquent 是基于 PHP 的 PDO,PDO 使用 prepared 来准备查询语句,保障了安全性。

在使用 raw() 来编写复杂查询语句时,必须 使用数据绑定。

错误的做法:

Route::get('sql-injection', function() {
    $name = "admin"; // 假设用户提交
    $password = "xx' OR 1='1"; // // 假设用户提交
    $result = DB::select(DB::raw("SELECT * FROM users WHERE name ='$name' and password = '$password'"));
    dd($result);
});

以下是正确的做法,利用 select 方法 的第二个参数做数据绑定:

Route::get('sql-injection', function() {
    $name = "admin"; // 假设用户提交
    $password = "xx' OR 1='1"; // // 假设用户提交
    $result = DB::select(
        DB::raw("SELECT * FROM users WHERE name =:name and password = :password"),
        [
            'name' => $name,
            'password' => $password,
        ]
    );
    dd($result);
});

DB 类里的大部分执行 SQL 的函数都可传参第二个参数 $bindings ,详见:API 文档

策略6:接口做数据登录校验,确保不越权

例如查看服务单详情,通过服务单ID查询到详情后,需要判断下当前登录的公司ID跟服务单中的公司ID是否一致。

$loginuser = [];
$workorder = [];
if ($loginuser['company_id'] != $workorder['company_id']) {
    throw new Exception('你没有当前数据的访问权限');
}

策略7:使用白名单和黑名单过滤的方式避免批量赋值带来的安全威胁

Laravel 提供白名单和黑名单过滤($fillable 和 $guarded),开发者 应该 清楚认识批量赋值安全威胁的情况下合理灵活地运用。

批量赋值安全威胁,指的是用户可更新本来不应有权限更新的字段。举例,users 表里的 is_admin 字段是用来标识用户『是否是管理员』,某不怀好意的用户,更改了『修改个人资料』的表单,增加了一个字段:

<input name="is_admin" value="1" />

这个时候如果你更新代码如下:

Auth::user()->update(Request::all());

此用户将获取到管理员权限。可以有很多种方法来避免这种情况出现,最简单的方法是通过设置 User 模型里的 $guarded 字段来避免:

protected $guarded = ['id', 'is_admin'];

策略8:避免错误信息被屏蔽或直接显示

1、Laravel项目关闭 DEBUG,DEBUG开启时会暴露很多服务器的敏感信息,如果被黑客获得,将会造成很严重的安全问题,生产环境确保APP_DEBUG=false
2、避免全局try{}catch(){}
3、线上环境关闭错误报告(error_reporting,dislay_erros)
4、使用sentry捕获代码运行错误

策略9:其他安全策略

1、尽量使用PHP的最新版本,最新版本修复了已知的很多安全漏洞和bug
2、Register Globals,弃用(移除)的特性,不要使用
3、魔术引号特性,不要开启,在PHP-5.4中已经被移除

参考

posted @ 2021-04-12 00:15  shawnlee07  阅读(16)  评论(0)    收藏  举报