![为什么 modsecurity 要求 POST 请求中包含 Content-Length?](https://linux22.com/image/493686/%E4%B8%BA%E4%BB%80%E4%B9%88%20modsecurity%20%E8%A6%81%E6%B1%82%20POST%20%E8%AF%B7%E6%B1%82%E4%B8%AD%E5%8C%85%E5%90%AB%20Content-Length%EF%BC%9F.png)
我有一个 RESTful Web 服务,它接受对没有实体主体的资源的 POST 请求,例如空的 POST 请求。默认的 modsecurity 配置要求所有 POST 请求都具有 Content-Length:
# Require Content-Length to be provided with every POST request
SecFilterSelective REQUEST_METHOD "^POST$" chain
SecFilterSelective HTTP_Content-Length "^$"
modsecurity 控制台将此报告为 PROTOCOL_VIOLATION/EVASION。然而,根据我的阅读,我不认为这是真的HTTP/1.1 RFC。允许服务器要求 Content-Length(返回 400 或 411),但我没有看到任何内容说服务器必须(或建议它应该)以这种方式运行。
这可能因浏览器而异,但 Flash 客户端发出没有实体主体的 POST 请求时不会发送请求标头。执行“curl -XPOST ...”时 curl 也不会发送请求标头。出于这些原因,并且因为我认为 modsecurity 规则是对 HTTP 规范的误解,我正在考虑在我们的配置中取消对 POST 请求的 Content-Length 标头的要求。
有谁知道这条规则是为了解决什么特定漏洞而创建的?我搜索了无数次,但只找到一些参考资料,称这是库存 modsecurity 配置的一部分。
答案1
首先,您应该知道您正在运行 ModSecurity 的旧版本(分支 1.x)。如果您正在运行 Apache 2.0.x,则应升级到 ModSecurity 2.x。如果您仍在运行 Apache 1.3.x,那么恐怕您别无选择,因为 ModSecurity 2.x 无法与其配合使用。ModSecurity 1.x 本身并不存在漏洞,但其规则引擎对于当今的需求来说太不灵活了。
如果我没记错的话,ModSecurity 1.x 要求 POST 请求指定内容长度,纯粹是因为它不支持分块请求主体(提交请求主体的另一种方式,其中总长度直到最后才知道)。当时分块请求主体非常少见(我们说的是 2003 年、2004 年),现在也很少见(尽管有些移动设备正在使用它们)。
ModSecurity 2.x 中没有这样的限制。
如果删除该规则,您将创建一个大漏洞,有人可以通过该漏洞潜入攻击而不被发现。另一方面,我可以说,如果您运行的是 ModSecurity 1.x,还有其他方法可以做到这一点。或者,调整规则以拒绝设置了 Transfer-Encoding 请求标头的请求。这样做应该是安全的。
披露:我编写了 ModSecurity。
答案2
我相信该要求是 xml-rpc 规范的一部分,而不是 http 规范的一部分。如果您不关注 xml-rpc,我认为忽略它是可以的。
我不太了解它被普遍纳入 mod_security 的原因,除非它最初是为了防止某种深奥的缓冲区溢出。