V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
cohen121
V2EX  ›  问与答

阿里云对象存储-前端直传场景下上传大小和次数限制问题请教

  •  
  •   cohen121 · 2023-05-17 16:16:50 +08:00 · 1183 次点击
    这是一个创建于 567 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用场景: 后端用 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

    11 条回复    2023-05-17 16:49:02 +08:00
    1343EFF
        1
    1343EFF  
       2023-05-17 16:26:03 +08:00
    你没有仔细看文档吧,前阵子正好写了一个 oss 直传插件,密钥校验那里是可以限制文件大小和文件路径,还有 sts 有效期(一般 3 分钟),但是文件名控制不了,后来想了一个解决思路,就是 oss 区块里分成两个路径,temp 和 public 文件夹这样,一个公开,一个私有,默认上传的时候强制进入 temp 目录,因为目录是可以加密校验的嘛。然后文件名进行一次对称加密,方式大约就是文件名+密码对称 base64 后,前端直传 oss 那边会发起一个回调,带有已经上传的文件信息参数,如果服务器对这个回调请求参数进行 base 解码后发现文件名对不上,不进行任何操作,反之如果文件名 base 解码后对的上,那就是安全的请求,文件会直接挪进 public 目录里面,由阿里云 cdn 进行对外代理允许公开访问(不建议直接访问 oss 资源哈,流量贵)
    1343EFF
        2
    1343EFF  
       2023-05-17 16:29:11 +08:00
    最后服务器写一个定时 shell ,定期清理 temp 目录里的辣鸡上传文件(就是骗取服务器 sts 授权,但是私自篡改文件名和回调信息的,因为是私有目录,他们胡乱上传并不能跑起来流量)另外路径这一块最好带有上传者的 id 信息,后台统计 oss 空间占用的时候,哪个 id 存在滥用,直接 ban 账号,就不给它 sts 授权了,反正这个就是挺绕的,中间攻击手段都得考虑到
    1343EFF
        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>
    1343EFF
        4
    1343EFF  
       2023-05-17 16:34:18 +08:00
    不会贴代码 php 的 凑合着看吧
    mozhizhu
        5
    mozhizhu  
       2023-05-17 16:35:19 +08:00
    每个文件路径单独签名,前端 PUT 上传;
    mozhizhu
        6
    mozhizhu  
       2023-05-17 16:36:09 +08:00
    好像是我理解错了……
    billlee
        7
    billlee  
       2023-05-17 16:36:32 +08:00 via Android
    可以用服务端签名后直传那个方案
    cohen121
        8
    cohen121  
    OP
       2023-05-17 16:37:49 +08:00
    @1343EFF #3 感谢老哥,get 到了,在 policy 添加 conditions 。 其他处理思路也很有借鉴👍
    huijiewei
        9
    huijiewei  
       2023-05-17 16:39:23 +08:00
    用直传回调来做后期限制。比如超出限制的回调里面直接调用 API 删除文件就好了。
    gam2046
        10
    gam2046  
       2023-05-17 16:48:49 +08:00
    根据 s3 的经验,可以让前端申请签名的时候,带上文件大小,类型,如果能前端算出来散列值也一起带上,后端直接给出预签名的 PUT URL ,同时把大小、类型这些都加入签名的计算中,同时前端上传到一个固定 prefix 的路径,后端二次校验后,移动到正式路径,这一步思路和#1 是一样的,但是删除不需要自己写脚本,利用对象的生命周期规则,可以自动删除,这样前端基本没有作法的空间了。
    1343EFF
        11
    1343EFF  
       2023-05-17 16:49:01 +08:00
    @cohen121 哦对想起来了目录是不能做权限区分的 只能是整个 oss 块都设置成私有的 然后给 cdn 服务 ram 授权,但是 cdn 访问规则那里要写死了只能访问 public 目录这样。希望对你有帮助,因为那个插件本来打算开源的,但是还有好多功能没完善就不敢放出来丢人了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5746 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 03:22 · PVG 11:22 · LAX 19:22 · JFK 22:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.