事故(故事)
血亏 2 万,一个 OSS 安全漏洞,心服口服!也许下个踩坑的就是你。。
连续创业者(==持续亏损、失败),小A收购了个类似于 Pinterest 的网站,用户可以在里面上传图片,现在都是用的 OSS + CDN ,不自己搞磁盘阵列了。非常的方便。
[惬意喝咖啡]
突然有一天发现某云账号欠费,网站图片全部打不开了。
[脑瓜子嗡嗡的]
不对啊,CDN 和 OSS 都加了 referer 检验,不会哪个 APP 这么无良引用了我的图片吧。打开 OSS 控制台看了下统计。
[什么鬼]
什么鬼,一个图片访问 2554 次,用了 1.57T 的流量?
怎么会这么大的图片?不是在上传的时候限制了15M吗?不会AK泄密了吧?
[黑人问号]
文件名是路径都是严格按照流程来的,看来是程序漏洞,如果是 AK 泄漏,文件路径不会模拟的这么完整。
TMD,这些灰产拿哥的 OSS 和 CND 当最快的 FTP 呢?我下载了一个,用file
命令看了下是mp4
,我直接修改后缀,发现是一些电影。
电影比较枯燥,我就帮你们看了。
破案
冷静下来梳理下,流程上是这样的:用户选择本地文件,然后前端拿着本地文件的信息跟后端要一个PutObject
的上传 url 和临时 token,然后前端直传。这样做上传更高效,不用浪费后端的 I/O
。
这里有一点想当然了,就是在生成签名的时候,指定了图片的长度,但是...
headers.put("Content-Length", imageSize.toString());
request.setHeaders(headers);
URL signedUrl = ossClient.generatePresignedUrl(request);
但是在实际后面上传的时候不会拿这个值进行二次校验,太坑爹了!!!。
只能说灰产,你们是真牛,各种逆向思维,各种找漏洞。
我觉得 putobject 的官方文档 应该显著的提醒用户存在这个风险。
官方文档上的 直传的最佳实践方案已经更新 也升级了,现在使用的应该是 PostObject
可以更好的配置上传策略(Policy)以限制上传操作。
怎么解决
这些祖传代码,我也不敢动啊。牵一发动全身,改一个地方,要回归一个月,只能打补丁。某云上的 oss 有触发器,就增加了个函数计算脚本来处理,发现大于15M的文件就设置成私有,过了1天,灰产就不再上传了。
如果你项目中也有类似的case,换成PostObject
的方案吧。