问题描述
我正在开发一个服务器,它接受来自用户的 URL 并下载它(并对其执行其他操作,例如将其上传回来,但这在这里无关紧要)。它应该接受的最大文件大小为 4 GB,这就是用户提供的 URL 必须存在 Content-Length 的原因。
但是,如果说,恶意服务器提供 2 GB 的内容长度,而最终传输的是 6 GB,会发生什么情况?是否有适当的机制来阻止这种情况?我正在使用 Rust 库 reqwest,但其他 HTTP 客户端的答案也会很棒。
解决方法
一个常见的实现将只获取 Content-length
并读取指定数量的数据 - 将剩余的数据留在套接字缓冲区(或者可能是一些用户空间缓冲区)中。因此它可能适用于这个特定的请求。
但是在 HTTP 持久连接的情况下,这实际上可能会导致问题。对于 Content-length
太短的请求,剩余数据将被解释为同一连接上的另一个 HTTP 请求。对于具有类似问题的响应,剩余数据将被解释为对连接上下一个请求的响应。在最好的情况下,由于数据格式错误,这将被视为错误,并且请求将被放弃。在最坏的情况下,它可能会导致安全问题 - 另请参阅作为相关攻击的 HTTP 请求和响应拆分。
... 这就是 URL 必须存在 Content-Length 的原因
请注意,请求或响应中实际上不需要 Content-length
。消息头可能没有指示响应的最终大小,因为它可能使用 Transfer-Encoding: chunked
或只是以 TCP 连接的关闭结束。