🦊【通用体系】你司暴露的上传接口被黑产用来上传小视频?做一套安全的上传体系来防范吧!🦄️

4,347

你知道吗,如果你们公司向用户提供了上传功能,那可能这已经成为了黑产赚钱的摇篮,一个一个非法视频通过你们的CDN在用户之间传递,消耗着资源(每1GB可都是要钱的!),甚至可能还会有法务风险!那如何设计一套上传体系来完善上传的安全性呢?

我们这里更多的以云服务商(例如腾讯云)作为上传目标给大家参考,云服务厂商是为通用性而设计的,他们不会去做一些ROI低的事情,而自研就是想怎么玩就怎么玩,对能做的事情来说肯定是自研更多更有趣,但是鉴于小公司很难有一定的资源来做对象存储和CDN,所以这里大家可以按需来看。

对象存储和CDN

首先,我们需要先区分一下对象存储和CDN。

对象存储就是一个存储系统,简单来说就是把文件存储到磁盘。而CDN主要是负责分发资源的,帮助你很快的访问到全世界的资源(懂者自懂

业务隔离

在一个新系统成立之初时,首先业务需要向对象存储申请存储空间以及对应的业务的云服务对应用户名密码

申请存储空间(桶子)这一步对于业务线比较多的大公司来说是非常必要的,不仅从技术上来说,分空间管理能够尽量避免不同业务间相互影响,提升各个业务的稳定性;同时从财务上来说不同业务的存储空间可以分别进行计费;甚至如果一个业务线关停了,直接把这个业务线的存储空间整块回收。同时,针对一个业务,内部使用的存储空间与在外网可访问的存储空间也是隔离的,保证内网资源尽量不被泄露,也减少外网CDN等的资源消耗。

而申请的用户名密码一般是可以使用云服务商所有功能的,所以如果为了安全,还可以创建子账号来单独负责上传功能。

格式严格规定

在存储空间定下来后,每个上传的场景可以规定上传的文件类型、文件大小。

但是如果用的是云服务厂商(腾讯云OSS、阿里云OSS),它们是并没有提供限制上传的文件类型、大小的功能的。

做的简单一些的话,可以只做前端校验,但如果想要完美cover场景,就要选择经由后端上传,来进行一次格式大小判断了。

用户登录态

在网络审查越来越严格的现在,首先尽量不要设计非登录用户上传的功能,如果实在是需要这种场景,也需要使用类似指纹的方式记下上传者的相关信息,但还是会有风险存在。有了用户的id就可以用来做很多事情:例如下面说的指定用户上传路径、限制用户每日上传个数、包括最后的非法文件追源都需要登录态才能来做。

上传

整体的上传步骤可以看下图

未命名文件 (7).png

可以看到每次上传前端都会请求上传token,同时可以限制用户的上传路径,如果重复上传就覆盖,很大得提升了黑客的违法成本。

如果场景就是用户可以传多份资源,那就可以在向后端请求token时记录当天请求次数,如果超过一个数量级(比如100)就可以将该用户暂时封禁。黑产很大概率是通过代码上传资源的,所以这里也可以配合反爬的机制来进行参数加密等来防范非画面操作,想了解更多反爬可以看看这篇文章juejin.cn/post/705680…

这种请求上传token的方法也叫做验签,而验签的模式也分为两种:

  • 后端只下发token,不参与上传的流量运输

    • 前端在文件选择后,向后端请求上传的token,前端使用token上传
  • 后端来做上传

    • 前端直接将需要上传的文件发送给后端,后端上传到对象存储

可以看到,第一种方式的优点是上传流量只需要一次,但是后端必须给出一个包装token的接口给前端,前端在上传文件前必须先请求接口获取token;

第二种方式的优点是前端只需要将需要上传的文件提交给后端,所有工作后端完成,并且也可以做到上面我们说的文件格式大小限制,上传经由后端在业务层面也可以记更多的信息,然而,这样上传流量就需要通过后端转发一次,尤其是对大文件来说,不仅流量哗哗地烧,同时每个业务后端都需要实现断点续传的功能,不然用户体验会直线下滑。

相比较下来,包装一个token接口比实现断点续传的工作还是小很多的,因此许多公司都选择了第一种方式。

其实在整理这一块时考虑了另一个方案:

对象存储暴露出一个公钥,后端对必要字段进行加密后返回给前端,前端上传给对象存储后,对象存储可用私钥解密拿到需要的信息。

优点:

  1. 每次上传请求token时,后端不需要多请求一次对象存储
  2. 对象存储也可以不用将token落库,直接解密就可以判断

缺点

  1. 加密解密吃CPU性能
  2. 这个方案相对复杂,也要考虑到更换秘钥,而请求对象存储和对象存储落库这两点都不太会造成性能瓶颈

所以这套方案整体看来ROI不高,所以基本没有云服务厂商是那么实现的。

审核

审核这个步骤就需要公司的体量了,没有的不要强求,但是B站、小红书等出现的一些负面新闻可以说明审核也是上传的很重要的一部分。

图片、视频等在审核后才可以公网访问可以很好扼住黑客们的喉咙,但随之带来的就是成本的增加和实效的降低。

访问

访问的话本身来说很简单,先讲讲CDN的访问机制。

刚刚在上传part有讲到说用户上传的资源最后落到机房了,那这意味着什么呢?

比如用户在某处上传一个资源,资源就放在了一个机房中,当另一个用户访问时,CDN会距离这个用户由近至远得寻找这个文件,如果找不到,就去源地址获取,并且在寻找路径中的每层都存储这个文件。

所以第一批使用资源的用户体验是比较慢的,想要改善这个问题可以使用CDN预热,将资源自动备份,但这也是个空间换时间的操作,看项目情况决定。

但需要注意的是,国内的资源同步到国外很可能是违法的,所以在外网也需要访问的情况下,我们会选择国内传一份资源,国外也传一份。

所以说访问就是通过CDN来拿到最近机房的资源,那如果有一些别的需求呢?

比如之前提到的审核,图片在上传到存储空间后,审核需要存储的文件能够在内网审核系统中被访问,同时许多UGC场景需要上传的用户也可以从外网访问到这个文件,然而又需要避免被其他用户从外网访问。

动态控制访问

假设现在的场景是,用户可以发表带图评论,但是图片要经过审核后才能被其他用户看到。

那现在需要看到这张图的是内部的审核人员+发表该图的用户。

于是,在用户上传图片时我们可以将图片先上传到内网,给审核人员用来审核,在审核期间如果用户需要查看自己上传的图片的话,可以后端提供一个新接口,用来判断当前评论是否为审核中,如果是在审核中,就通过内网访问图片下载后,以blob的形式返回给前端展示。

等到审核结束,那分两种case,如果你们公司的CDN支持复杂的规则,那就可以简单的设置为过审的文件设为外网可访问,未过审仍旧只可内网;如果不支持,只能走复杂的逻辑,一旦审核通过,将资源传至外网数据存储,并通知数据库更新。

后记

这篇文章卡壳了很久才写完,写完之后回顾发现也没有很长23333,灵感来源于线上的一个上传设计不当导致的问题,因为对这一块一开始也不太了解,所以也请求了一些专业同学的帮助来让我理清了这一块,现在分享给大家~