Why does modsecurity require Content-Length in POST requests?
I have a RESTful web service that accepts a POST request to a resource without an entity body, e.g. an empty POST request. The default modsecurity configuration requires that all POST requests have a Content-Length:
# Require Content-Length to be provided with every POST request
SecFilterSelective REQUEST_METHOD "^POST$" chain
SecFilterSelective HTTP_Content-Length "^$"
The modsecurity console reports this as a PROTOCOL_VIOLATION/EVASION. However I don't see this as true in my reading of the HTTP/1.1 RFC. A server is allowed to require Content-Length (returning either 400 or 411), but I see nothing that says a server must (or a recommendation that it should) behave in this way.
This possibly varies by browser, but Flash clients making POST requests without entity bodies don't send a request header. Neither does curl when you do 'curl -XPOST ...'. For these reasons, and because I believe the modsecurity rule to be a misinterpretation of the HTTP spec, I'm considering lifting the requirement for a Content-Length header on POST requests in our config.
Does anyone know if there was a specific exploit this rule was created to address? Numerous google searches and I've only found references to this being part of the stock modsecurity configuration.
Solution 1:
First of all, you should know that you are running an obsolete version of ModSecurity (branch 1.x). If you are running Apache 2.0.x you should upgrade to ModSecurity 2.x. If you are still running Apache 1.3.x then I am afraid that you don't have a choice since ModSecurity 2.x won't work with it. ModSecurity 1.x itself is not known to be vulnerable, but its rule engine is too inflexible for today's demands.
If I recall correctly, ModSecurity 1.x required POST requests to specify content length purely because it didn't support chunked request bodies (the alternative way of submitting request bodies, in which the total length is not known until the end). Chunked request bodies were incredibly rare then (we're talking years 2003, 2004) and are still rare (although some mobile devices are using them).
There are no such restrictions in ModSecurity 2.x.
If you remove that rule you will create a big hole through which someone could sneak in an attack undetected. On the other hand, I can argue that, with you running ModSecurity 1.x, there are other ways to do the same. Alternatively, tweak the rule to refuse requests that have the Transfer-Encoding request header set. You should be safe with that.
Disclosure: I wrote ModSecurity.