使用场景: 后端用 sts 给前端分发临时 token ,前端直接用临时 token 上传图片到 oss. 问题描述: 这里用 sts 申请的 token 好像没法在 policy 里设置上传文件大小和次数的限制,这里的安全问题是攻击者可以拿着这个 token ,用脚本发生大量大文件到我的 oss 里。 我问了阿里云的人工客服答非所问,完全没理解我的意思,来 v 站问问有经验的老哥。另一种方式:用户上传到我的后端服务,后端再传给 oss ,这样可以解决上传滥用的问题,不过会有额外带宽的考虑。 阿里云的文档: https://help.aliyun.com/document_detail/100624.html
PS: 设置回调的方式好像是数据已经传输完成后才会触发,并不能有起到拦截的作用。https://help.aliyun.com/document_detail/31922.html?spm=a2c4g.31920.0.0.4a1c6d20mhCrid#section-nj2-jdy-5db
1
1343EFF 2023-05-17 16:26:03 +08:00
你没有仔细看文档吧,前阵子正好写了一个 oss 直传插件,密钥校验那里是可以限制文件大小和文件路径,还有 sts 有效期(一般 3 分钟),但是文件名控制不了,后来想了一个解决思路,就是 oss 区块里分成两个路径,temp 和 public 文件夹这样,一个公开,一个私有,默认上传的时候强制进入 temp 目录,因为目录是可以加密校验的嘛。然后文件名进行一次对称加密,方式大约就是文件名+密码对称 base64 后,前端直传 oss 那边会发起一个回调,带有已经上传的文件信息参数,如果服务器对这个回调请求参数进行 base 解码后发现文件名对不上,不进行任何操作,反之如果文件名 base 解码后对的上,那就是安全的请求,文件会直接挪进 public 目录里面,由阿里云 cdn 进行对外代理允许公开访问(不建议直接访问 oss 资源哈,流量贵)
|
2
1343EFF 2023-05-17 16:29:11 +08:00
最后服务器写一个定时 shell ,定期清理 temp 目录里的辣鸡上传文件(就是骗取服务器 sts 授权,但是私自篡改文件名和回调信息的,因为是私有目录,他们胡乱上传并不能跑起来流量)另外路径这一块最好带有上传者的 id 信息,后台统计 oss 空间占用的时候,哪个 id 存在滥用,直接 ban 账号,就不给它 sts 授权了,反正这个就是挺绕的,中间攻击手段都得考虑到
|
3
1343EFF 2023-05-17 16:33:34 +08:00
<pre>
//请求有效时间 默认 3 分钟 $expiration = str_replace('+00:00', '.000Z', gmdate('c', time() + 180)); //限制上传大小 默认 10MB $conditions = [ [0 => 'content-length-range', 1 => 0, 2 => (int)$config['maxSize'] * 1024 * 1024], [0 => 'starts-with', 1 => '$key', 2 => $dir], ]; $policy = json_encode(['expiration' => $expiration, 'conditions' => $conditions]); </pre> |
4
1343EFF 2023-05-17 16:34:18 +08:00
不会贴代码 php 的 凑合着看吧
|
5
mozhizhu 2023-05-17 16:35:19 +08:00
每个文件路径单独签名,前端 PUT 上传;
|
6
mozhizhu 2023-05-17 16:36:09 +08:00
好像是我理解错了……
|
7
billlee 2023-05-17 16:36:32 +08:00 via Android
可以用服务端签名后直传那个方案
|
8
cohen121 OP @1343EFF #3 感谢老哥,get 到了,在 policy 添加 conditions 。 其他处理思路也很有借鉴👍
|
9
huijiewei 2023-05-17 16:39:23 +08:00
用直传回调来做后期限制。比如超出限制的回调里面直接调用 API 删除文件就好了。
|
10
gam2046 2023-05-17 16:48:49 +08:00
根据 s3 的经验,可以让前端申请签名的时候,带上文件大小,类型,如果能前端算出来散列值也一起带上,后端直接给出预签名的 PUT URL ,同时把大小、类型这些都加入签名的计算中,同时前端上传到一个固定 prefix 的路径,后端二次校验后,移动到正式路径,这一步思路和#1 是一样的,但是删除不需要自己写脚本,利用对象的生命周期规则,可以自动删除,这样前端基本没有作法的空间了。
|