[beego]multipart form数据自动缓存可能导致磁盘被恶意提交的数据占满,能否增加开关控制

2023-12-15 768 views
5

描述: 我发现框架会自动在接口路由匹配前将multipart form数据缓存到磁盘中(当大于设定的允许内存读取大小时),并且缓存时是没有对大小进行限制的。该设计可能会导致客户端通过少量请求恶意提交大量数据将服务端磁盘临时占满。

当前处理方式: 增加一个BeforeStatic的过滤器,用于拦截所有携带multipart form数据的请求。不过该场景还是比较通用的,让每个使用beego框架的项目增加这个逻辑会比较冗余。

需求: 能否增加一个配置项用来控制是否由框架自动缓存呢?关闭的情况下,如果接口需要缓存,可以自行在handler中调用parsemultiform方法进行缓存。

相关代码行: https://github.com/astaxie/beego/blob/f6519b29a846bdf59a2b86baa011c242f78387d5/router.go#L753

回答

2

复现方式: 基于beego1.11版本编写并启动一个服务端,通过curl命令调用任意接口(路由无需匹配),通过-F参数提交一个2G大小的文件,可以在/tmp/目录下看到它被整个缓存到multipart-前缀的临时文件中。 image

1
4272 增强了这方面的控制,在超出MaxSize之后直接拒绝掉请求。

虽然我考虑过,看看能不能提供支持分片上传的类似于SaveFile的方法,但是,我最终否定了这个想法,理由是:

  1. 大文件上传,用户应该清醒意识到这是一个危险的操作,他可以选择增大MaxMemory参数来控制;
  2. 如果用户认为,增大MaxMemory是一个危险的举动,那么他就应该考虑分片上传了;

大文件上传对服务器的压力是极大的,尤其是在并发上传的情况下。

所以,直接拒绝掉请求而要求开发者有意识的控制MaxMemory或者自主支持上传大文件,会更加好一点。

3

突然觉得直接拒掉有点太粗暴,我再考虑额外控制一下……

3
4275 增加了MaxUploadSize来控制。原本考虑叫MaxBodySize或者MaxRequestSize,但是因为非上传文件,直接就使用了MaxMemory来控制RequestBody大小,所以只能换一个名字了。

我现在觉得这个方案还是很不错了。

< MaxMemory,上传的文件直接在内存

MaxMemory, < MaxUploadSize,一部分在内存,一部分在临时文件 MaxUploadSize,直接拒绝