Bug 66599 - DOS / Memory OOM from .htaccess
Summary: DOS / Memory OOM from .htaccess
Status: REOPENED
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: Core (show other bugs)
Version: 2.4.57
Hardware: PC Linux
: P2 major (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-05-12 13:48 UTC by K
Modified: 2023-05-12 20:02 UTC (History)
1 user (show)



Attachments
rewrite log, showing ever growing loop that causes oom (954.45 KB, application/gzip)
2023-05-12 15:36 UTC, K
Details

Note You need to log in before you can comment on or make changes to this bug.
Description K 2023-05-12 13:48:02 UTC
Hi All, 

This was highlighted from a clients site, he had a htaccess file containing 

---------------------------------------------
Header set Cache-Control "no-store"

RewriteEngine On
RewriteBase /

# If there are caps, set HASCAPS to true and skip next rule
RewriteRule [A-Z] - [E=HASCAPS:TRUE,S=1]

# Skip this entire section if no uppercase letters in requested URL
RewriteRule ![A-Z] - [S=28]

# Replace single occurance of CAP with cap, then process next Rule.
RewriteRule ^([^A]*)A(.*)$ $1a$2
RewriteRule ^([^B]*)B(.*)$ $1b$2
RewriteRule ^([^C]*)C(.*)$ $1c$2
RewriteRule ^([^D]*)D(.*)$ $1d$2
RewriteRule ^([^E]*)E(.*)$ $1e$2
RewriteRule ^([^F]*)F(.*)$ $1f$2
RewriteRule ^([^G]*)G(.*)$ $1g$2
RewriteRule ^([^H]*)H(.*)$ $1h$2
RewriteRule ^([^I]*)I(.*)$ $1i$2
RewriteRule ^([^J]*)J(.*)$ $1j$2
RewriteRule ^([^K]*)K(.*)$ $1k$2
RewriteRule ^([^L]*)L(.*)$ $1l$2
RewriteRule ^([^M]*)M(.*)$ $1m$2
RewriteRule ^([^N]*)N(.*)$ $1n$2
RewriteRule ^([^O]*)O(.*)$ $1o$2
RewriteRule ^([^P]*)P(.*)$ $1p$2
RewriteRule ^([^Q]*)Q(.*)$ $1q$2
RewriteRule ^([^R]*)R(.*)$ $1r$2
RewriteRule ^([^S]*)S(.*)$ $1s$2
RewriteRule ^([^T]*)T(.*)$ $1t$2
RewriteRule ^([^U]*)U(.*)$ $1u$2
RewriteRule ^([^V]*)V(.*)$ $1v$2
RewriteRule ^([^W]*)W(.*)$ $1w$2
RewriteRule ^([^X]*)X(.*)$ $1x$2
RewriteRule ^([^Y]*)Y(.*)$ $1y$2
RewriteRule ^([^Z]*)Z(.*)$ $1z$2

# If there are any uppercase letters, restart at very first RewriteRule in file.
RewriteRule [A-Z] - [N]

RewriteCond %{ENV:HASCAPS} TRUE
RewriteRule ^/?(.*) /$1 [R=301,L]

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1.html [NC,L]

DirectoryIndex index.html
ErrorDocument 403 https://www.mosascollection.uk/error/403
ErrorDocument 404 https://www.mosascollection.uk/error/404
ErrorDocument 500 https://www.mosascollection.uk/error/505
ErrorDocument 503 https://www.mosascollection.uk/error/503
Options -Indexes
-------------------------------------------

and then when making a request to the site url, 

wget mosascollection.uk///wp-includes/ID3/license.txt

httpd event would sit and consume ram till server swapped out, and then oom'd 

Please not the file wp-includes/ID3/license.txt did NOT exist, and the /// may be part of the cause. 

This is obviously a DOS vector, and if any more information is required please ask. 

best regards
K
Comment 1 K 2023-05-12 14:01:28 UTC
Hi All, 

Commenting out 

----------------------

# Replace single occurance of CAP with cap, then process next Rule.
#RewriteRule ^([^A]*)A(.*)$ $1a$2
#RewriteRule ^([^B]*)B(.*)$ $1b$2
#RewriteRule ^([^C]*)C(.*)$ $1c$2
#RewriteRule ^([^D]*)D(.*)$ $1d$2
#RewriteRule ^([^E]*)E(.*)$ $1e$2
#RewriteRule ^([^F]*)F(.*)$ $1f$2
#RewriteRule ^([^G]*)G(.*)$ $1g$2
#RewriteRule ^([^H]*)H(.*)$ $1h$2
#RewriteRule ^([^I]*)I(.*)$ $1i$2
#RewriteRule ^([^J]*)J(.*)$ $1j$2
#RewriteRule ^([^K]*)K(.*)$ $1k$2
#RewriteRule ^([^L]*)L(.*)$ $1l$2
#RewriteRule ^([^M]*)M(.*)$ $1m$2
#RewriteRule ^([^N]*)N(.*)$ $1n$2
#RewriteRule ^([^O]*)O(.*)$ $1o$2
#RewriteRule ^([^P]*)P(.*)$ $1p$2
#RewriteRule ^([^Q]*)Q(.*)$ $1q$2
#RewriteRule ^([^R]*)R(.*)$ $1r$2
#RewriteRule ^([^S]*)S(.*)$ $1s$2
#RewriteRule ^([^T]*)T(.*)$ $1t$2
#RewriteRule ^([^U]*)U(.*)$ $1u$2
#RewriteRule ^([^V]*)V(.*)$ $1v$2
#RewriteRule ^([^W]*)W(.*)$ $1w$2
#RewriteRule ^([^X]*)X(.*)$ $1x$2
#RewriteRule ^([^Y]*)Y(.*)$ $1y$2
#RewriteRule ^([^Z]*)Z(.*)$ $1z$2

-------------------------

fixed the DOS, I would 'guess' that its due to the 'ID' capital ID, being in the request uri, obviously this is not expected behavior, and on a shared hosting platform where apache is used could cause some big issues. 

best regards
K
Comment 2 Eric Covener 2023-05-12 14:09:39 UTC
It is hard to tell the expected behavior of the convoluted ruleset, mod_rewrite provides an internal map function to lowercase input without doing it 1 character at a time and looping with [N].

Did the behavior change? Does the rewrite trace give any idea of what's happening?
Comment 3 K 2023-05-12 14:43:50 UTC
Hi there,

Please feel free to reproduce it using the rules / request supplied, all I know at this moment is if I upload that to any shared hosting provider using apache 2.4 then it will OOM the server where ran, and is hard to identify as mod_rewrite rules are ran as the nobody / httpd / apache user.

best regards
K
Comment 4 K 2023-05-12 14:45:27 UTC
Hi there,

Also just for your info, this used over 50GB of ram on the one 'simply' request. 

best regards
K
Comment 5 K 2023-05-12 15:36:09 UTC
Created attachment 38555 [details]
rewrite log, showing ever growing loop that causes oom

Hi all,

On checking further done a little debug / logging of rewrite using 

LogLevel alert rewrite:trace6

and have attached the pertinent part of the log.

Log shows the redirect causing an ever increasing redirect loop, causing ram to become exhausted, internal redirects are not hit, and httpd runs till it oom's .
Comment 6 Eric Covener 2023-05-12 15:50:34 UTC
The repeating "add path info postfix" is related to the missing file, the remainder of the URL is treated as PATH_INFO.  The config indirectly continually adds uppercase characters during the scan for uppercase characters.

for the functional issue, use the internal tolower rewritemap.

I believe the answer on security@apache.org would be that it requires the attacker to have write access to the config (incl htaccess) and we would not consider it a vulnerability.  This case may be inadvertent but it's not idiomatic at all.
Comment 7 K 2023-05-12 15:58:26 UTC
Hi there, 

So a shared hosting server where a client has access to write to their home folder to cause the httpd process to DOS all clients is allowed, or for example a website where a hacker uses a vulnerable script (think wordpress plugins , etc ) to add these rules, to then make a request to httpd to take the server down / DOS the server is not a considered a vulnerability in httpd, surly httpd should have some form of sanity in it to stop processing after so long (like the limitinternalrequests) in situations like this rather than spinning and OOM'ing the server. 

best regards
K
Comment 8 Ruediger Pluem 2023-05-12 19:36:10 UTC
What is your setting of LimitRequestLine? Or don't you set it?
Comment 9 K 2023-05-12 20:02:44 UTC
hi there,

LimitRequestLine is not set, so should be default of 8190

best regards
K