Apache HTTPD 2.4 AH02429 error with phantom response header - apache

I've an Apache HTTPD 2.4.37 which, since this morning, is responding with 500 and [Mon Jan 24 12:27:03.132322 2022] [http:error] [pid 3650579:tid 140496433313536] [client 10.42.0.47:53214] AH02429: Response header name '[Mon Jan 24 12' contains invalid characters, aborting request while trying to render a Perl application.
If I try to call the website with curl -v I cannot see such "header" in the response headers.
Morevoer, if I copy the conf.modules.d folder from an Apache HTTPD 2.4.6 version it then works as expected.

After some backtracking, it seems like that a request header I'm setting it's breaking the request when this is empty.
I was following https://httpd.apache.org/docs/2.4/env.html#fixheader to propagate an "invalid" (for Apache HTTPD) header and the regex used there matches even if the value of the header is empty (i.e. the header is not part of the request at all).
In such a case, for some reason the request gets broken.

Related

Apache server reverse proxy: increase file upload limit

I'm configuring a httpd to perform as a reverse proxy which should allow file uploads as well. Average file size is around 20MB. With basic configurations I could only upload files of max size 128KB.
After referring some materials, I installed modsecurity plugin to enable uploading files with max allowance of 30 MB.
In the mod_security.conf file, I have:
SecRuleEngine On
SecRequestBodyAccess On
SecRequestBodyLimit 31457280
SecRequestBodyNoFilesLimit 131072
SecRequestBodyInMemoryLimit 1048576
SecRequestBodyLimitAction Reject
SecRule REQBODY_ERROR "!#eq 0" "id:'200001', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
But if I try to upload even 1MB file, I get the below error:
[:error] [pid 7877] [client 10.192.10.186:47406] [client 10.192.10.186] ModSecurity: Multipart parsing error (init): Multipart: Invalid boundary in C-T (malformed). [hostname "<host>"] [uri "<uri>"] [unique_id "YmE-3e7SizASbXjV8cTWfQAAAAQ"]
[proxy:error] [pid 7877] (32)Broken pipe: [client 10.192.10.186:47406] AH01084: pass request body failed to 10.192.21.143:443
[proxy_http:error] [pid 7877] [client 10.192.10.186:47406] AH01097: pass request body failed to 10.192.21.143:443 () from 10.192.10.186 ()
The questions I have are:
Am I using the correct plugging?
What is the error in the above configuration?
OWASP ModSecurity Core Rule Set dev-on-duty here. Your error is the first alert message: "Multipart parsing error (init): Multipart: Invalid boundary in C-T (malformed)." The rest is Apache reacting to the ModSecurity parsing abort.
Based on my experience with ModSecurity I am confident we're facing a malformed multipart request. Try to submit a multipart request with curl to see if it works out. If it does, as I suspect, you need to look at your client. Probably by taking a very close look at the request body and the Content-Type header.

How to get "my" VHOST in code executed by PerPostConfigRequire?

I'm hosting multiple instances of the same web app in different versions using the same instance of HTTPd and one VHOST per instance/version of web app currently. I would like to use mod_perl's PostConfigRequire to implement a handler pre-loading all those instances during server startup instead of relying on mod_perl's registry-facilities per request, as is done currently. The latter breaks in case of too many concurrent requests and according to some tests, that problem doesn't occur anymore in case things get pre-loaded.
Because of the different versions of my web app, I need to use PerlOptions +Parent to provide each VHOST with its individual Perl interpreter pool. Additionally I can easily configure PerlPostConfigRequire per VHOST, but pre-loading needs to take into account which VHOST that handler is currently executed in. Within that handler I need to only load those files associated with some concrete VHOST.
The problem is that I'm having trouble how to find the VHOST currently executing that handler. In that past I have implemented something similar per request by looking at the currently requested URL and comparing that to VHOST configs, but I don't have a request now. Apache2::ServerUtil->server() is not providing my VHOST, but it's available at all e.g. using Apache2::Directive::conftree()->lookup('VirtualHost'). Only that I don't know which one is the one containing PerlPostConfigRequire currently executed. I'm pretty sure that PerlPostConfigRequire really gets executed per VHOST, because I get debugging output scaling with the number of VHOSTs configured as well.
Any ideas? Thanks!
The only thing which came into my mind is using environment variables per VHOST like in the following example. PerlSetVar doesn'T work because it's per request only and not available during startup of the web server.
PerlSetEnv SOME_ID "0c8c1236-86de-4483-9d4b-999e2cfd17c1"
PerlPostConfigRequire "Some.pm"
Each VHOST gets it's own ID and that environment variable seems to be uniquely available during execution of the configured package:
[Mon Aug 05 20:50:32.181559 2019] [:warn] [pid 17736:tid 704] [...]: 0c8c1236-86de-4483-9d4b-999e2cfd17c1: 1
[Mon Aug 05 20:50:32.836195 2019] [:warn] [pid 17736:tid 704] [...]: 9dc691d6-794a-4095-852e-e596cabf43d5: 1
[Mon Aug 05 20:50:34.180453 2019] [:warn] [pid 17736:tid 704] [...]: 0c8c1236-86de-4483-9d4b-999e2cfd17c1: 2
[Mon Aug 05 20:50:34.830098 2019] [:warn] [pid 17736:tid 704] [...]: 9dc691d6-794a-4095-852e-e596cabf43d5: 2
The logging code:
my $server = Apache2::ServerUtil->server();
$server->warn(__PACKAGE__ . ": $ENV{'SOME_ID'}: " . Apache2::ServerUtil::restart_count());
With that in mind, one can get all VHOSTs and search for the ID they define. It's important to note that lookup is not of much help here, it doesn't seem to support searching for PerlSetEnv directly, but one needs to implement that on hash refs returned for the VHOSTs manually:
my $confTree = Apache2::Directive::conftree();
my #vhosts = $confTree->lookup('VirtualHost');
Each result is a hash ref containing keys and values like the following:
$VAR1 = {\n 'PerlSetEnv' => 'AMS_MOD_PERL_PRE_LOADING_ID "9dc691d6-794a-4095-852e-e596cabf43d5"',\n[...]
'PerlSetEnv' => [\n '"AMS_MOD_PERL_PRE_LOADING_ID" "9dc691d6-794a-4095-852e-e596cabf43d5"',\n '"murks" "test"'\n ],
The structure of the hash ref depends on the actual config, so it might contain additional child hash refs I guess. Any better ideas welcome...

Apache LimitRequestFieldSize Directive does not work

I'm running my website on apache 2.2 and when the HTTP request header size is above 8K I get a HTTP 400 error -
Bad Request
Your browser sent a request that this server could not understand.
Size of a request header field exceeds server limit.
cookie /n
And the error in Apache error_log is -
[Fri Jul 24 18:52:56 2015] [error] [client XX.XX.XX.XX] request failed: error reading the headers
This is expected but when I set allowed limit to 16k by -
LimitRequestFieldSize 16380
I still get the same HTTP 400 error on the browser but this time I don't see any error apache error_log.
I have tried using higher values with LimitRequestLine and LimitRequestFields but it doesn't work. Is there any thing I'm missing here ?

Apache 2 error log only shows the error message "0"

Since a few days, my Apache 2 error log is showing a lot messages like the following (IP addresses and URIs redacted):
[Thu Dec 12 13:46:42 2013] [error] [client 111.222.333.444] 0
[Thu Dec 12 13:52:27 2013] [error] [client 222.333.444.555] 0, referer: http://www.mydomain.com/
[Thu Dec 12 13:52:27 2013] [error] [client 222.333.444.555] 0, referer: http://www.mydomain.com/
[Thu Dec 12 13:53:54 2013] [error] [client 333.444.555.666] 0, referer: http://www.mydomain.com/subdirectory/
[Thu Dec 12 13:46:42 2013] [error] [client 444.555.666.777] 0
[Thu Dec 12 13:54:07 2013] [error] [client aaaa:1111:2222:ffff::] 0, referer: http://www.otherdomain.com/subdirectory/
What is this 0? There are no other messages shown (besides sometimes some other, normal messages, but very rarely).
The IP addresses are both IPv4 and IPv6. I checked the access log for the same date/time and IP addresses. Most of the times, there was an access for the exact same moment from this IP for different URIs on my webpage. But sometimes, there wasn't an access according to the access log.
It's a shared hosting environment, so I can't access the Apache settings (but I have ssh access to my home directory if this helps). I already googled and searched the Apache documentation, but didn't found anything (it's hard to search for "0"...)
/edit: I also asked the webhoster, they said they don't know what it's causing. I cross checked it with the Apache access log, these are requests to PHP scripts (mostly Joomla), but also requests to images as well as JS and CSS files. So I assume it's not a PHP script which is causing this.
If your error_log directive is unset errors will be written in your Apache log file for current VirtualHost.
So double check your PHP configuration (php.ini) or write a simple page with phpinfo()
If this is true, you should look inside your code (may be even into index.php).
Pay attention to this: usually there are two separate php.ini files for Apache /etc/php5/apache2/php.ini and CLI configuration /etc/php5/cli/php.ini.
Please also consider that, if you want change your PHP configuration, you can use ini_set function.
ini_set('error_log', '/var/log/php/error_new.log');
Remember: the destination directory must exist and your web server (or php engine) must have all permission to write into.
error_log format is not customizable, I suspect that it can be set to some higher level: debug or trace, where it can produce additional information.
Also please take into account, that error_log contains debug info from CGI/PHP/Perl scripts, so that 'zero' can be produced by some script that executed through apache as its module.

mod_jk.log shows what url?

I have mod_jk connector between Apache and Tomcat (on Ubuntu) and I'm looking at the mod_jk.log. The log mainly looks like this:
[Fri Jan 18 18:37:32 2013]ajp13 <some url from my domain> 0.011095
But occasionally I see these entries:
[Fri Jan 18 21:09:58 2013]ajp13 www.bradesco.com.br 0.030327
[Fri Jan 18 21:09:58 2013]ajp13 www.bb.com.br 0.009310
[Fri Jan 18 21:09:58 2013]ajp13 www.santander.com.br 0.011401
[Fri Jan 18 21:09:58 2013]ajp13 www.banese.com.br 0.010602
Does anybody know what urls are logged in mod_jk.log? Are these "br" entry legitimate?
Thanks.
The issue is not specific to mod_jk in any way, it just was initially observed in mod_jk logs.
All Brazilian URLs are coming from Host header property of the GET request. And as suggested in this comment this is a scan for open proxies.
Interesting enough it comes from the same IP address (65.111.177.188) for many months.
To shut this garbage out I added an extra rule to the mod_security conf file on the server:
SecRule &REQUEST_HEADERS:Host "!#pm mydomain" "phase:1,deny"
so that all hosts without mydomain in them are denied right away.