Bug 60478

Summary: [Patch] mod_rewrite local DOS using path info
Product: Apache httpd-2 Reporter: Jeff W <apache>
Component: mod_rewriteAssignee: Apache HTTPD Bugs Mailing List <bugs>
Severity: critical Keywords: FixedInTrunk
Priority: P2    
Version: 2.4-HEAD   
Target Milestone: ---   
Hardware: PC   
OS: FreeBSD   
Attachments: Patch to limit expansion by looping mod_rewrite rules

Description Jeff W 2016-12-14 16:13:18 UTC
Created attachment 34524 [details]
Patch to limit expansion by looping mod_rewrite rules

The following .htaccess will cause a local DOS:

RewriteEngine On
RewriteRule ^(.*)X(.*)$ $1x$2
RewriteRule X - [N]

This sequence of rules causes any moderately long request with path info containing a capital X (e.g. http://www.example.com/the/X/factor/causes/a/server/crash ) to loop repeatedly, appending path info (and thus a new X) to r->filename each iteration.  Each apr_pstrcat allocates a whole new string for the lifetime of the request.

The resulting memory usage is roughly M*N+O*N*(N-1)/2, where M is the size of the filename and O is the size of the path info.  With the default N=32000, even modest values (M=50, O=24) cause disproportionately enormous memory use (about 12GiB) after 32000 iterations.  Larger requests (M=1024, O=768) can easily consume hundreds of gigabytes, typically resulting in swap exhaustion or OOM aborts.  Both outcomes disrupt normal server operations, particularly with threaded MPM's.

As a result, an attacker who can cause an .htaccess file to be placed on the server (either through local access or e.g. through a scripting vulnerability) can subsequently cause disruption at any time by sending a relatively innocuous-appearing request.  (And due to the resulting crash, that request will not even be logged in most setups.)

This is a known issue; to quote a comment in bug 38642, "this bug is deadly in combination with the N-flag."  It can be prevented by the use of the DPI flag, which appears to be the resolution of 38642.

However, users cannot be relied upon to be aware of and use this flag, especially if disrupting server operations is their goal.  It seems undesirable to allow unprivileged users to crash the server process.

To resolve this issue, we have applied the attached patch.  After each RewriteRule, it checks to see if the result exceeds the value set by LimitRequestLine.  If so, it aborts the request.

LimitRequestLine is arguably not the right value here, although it is a decent heuristic default, as it already effectively limits the maximum length of a URL.  It certainly seems more suitable than the 100+GiB URLs being generated in this fashion before applying this patch.
Comment 1 Eric Covener 2016-12-14 16:27:57 UTC
Thanks for the report and patch. I applied it but doubled LimitRequestLine just for some leeway.  Will propose for 2.4.x.
Comment 2 Jeff W 2016-12-14 16:46:20 UTC
Thanks Eric!
Comment 3 Eric Covener 2016-12-14 22:29:30 UTC
Backport is complete and should be in 2.4.24. For posterity: We don't consider most intentional or unintentional config problems as vulnerabilities, but if there's any question about a report, it's best to start with security@httpd.apache.org so it can be reviewed.
Comment 4 Eric Covener 2016-12-31 00:25:05 UTC
Fixed in 2.4.25