Apache server reverse proxy: increase file upload limit - apache

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.

Related

Apache HTTPD 2.4 AH02429 error with phantom response header

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.

Real Time Malaware scanning using Maldetect : Rejected by the approver script

I have a cPanel server with apache 2.4 and Maldetect, ClamAV. I want to have realtime malware scanner on server to block hackers from uploading malicious files on server. What i meant is when someone uploads a file, apache will invoke the scanner using mod-security 2.9 and scan the uploaded file.
If it's found as malware - should get rejected.
If it's found good file - should upload to correct destination.
I have tried to do this with following settings as described in https://www.rfxn.com/appdocs/README.maldetect
To enable upload scanning with mod_security2 you must set enable the public_scan option
in conf.maldet (public_scan=1) then add the following rules to your mod_security2
configuration. These rules are best placed in your modsec2.user.conf file on cpanel servers
or at the top of the appropraite rules file for your setup.
/usr/local/apache/conf/modsec2.user.conf (or similar mod_security2 rules file):
SecRequestBodyAccess On
SecRule FILES_TMPNAMES "#inspectFile /usr/local/maldetect/hookscan.sh" \
"id:'999999',log,auditlog,deny,severity:2,phase:2,t:none"
If using ModSecurity >=2.9, you should set 'SecTmpSaveUploadedFiles On' before the
'SecRule FILES_TMPNAMES' line.
A restart of the Apache service is required following these changes.
But the problem is all the files are getting rejected by doing this, even good files. Is there anything wrong with the above setup?
# cat /usr/local/apache/conf/modsec2.user.conf
### UPLOAD PARAMETERS BEGIN ####
SecUploadDir /tmp
SecTmpDir /tmp/
SecDataDir /tmp/
SecUploadKeepFiles RelevantOnly
### UPLOAD PARAMETERS END ####
SecRequestBodyAccess On
SecTmpSaveUploadedFiles On
SecRule FILES_TMPNAMES "#inspectFile /usr/local/maldetect/hookscan.sh" \
"id:'999999',log,auditlog,deny,severity:2,phase:2,t:none"
Following is the error in logs
[Sun Mar 05 21:11:35.936553 2017] [:error] [pid 9800] [client x.x.x.x] ModSecurity: Access denied with code 406 (phase 2). File "/tmp/20170305-211135-WLxNz#kP#rKcABIc7ZF3lAAAAAM-file-SfujtQ" rejected by the approver script "/usr/local/maldetect/hookscan.sh": Linux Malware Detect v1.5 [file "/usr/local/apache/conf/modsec2.user.conf"] [line "13"] [id "999999"] [severity "CRITICAL"] [hostname "x.x.x.x"] [uri "/test.php"] [unique_id "WLxNz#kP#rKcABIc7ZF3lAAAAAM"]
[Sun Mar 05 21:11:44.511418 2017] [:error] [pid 9526] [client x.x.x.x] ModSecurity: Access denied with code 406 (phase 2). File "/tmp/20170305-211144-WLxN2EJsvK1FL3paCDmxrgAAAAE-file-iQx2zR" rejected by the approver script "/usr/local/maldetect/hookscan.sh": Linux Malware Detect v1.5 [file "/usr/local/apache/conf/modsec2.user.conf"] [line "13"] [id "999999"] [severity "CRITICAL"] [hostname "x.x.x.x"] [uri "/test.php"] [unique_id "WLxN2EJsvK1FL3paCDmxrgAAAAE"]
I had this issue too. Problem is this line:
SecTmpSaveUploadedFiles On
Try to remove it from the rule.

mod_security: A rule to allow POST requests without a request body

I have Apache 2.4 and mod_security 2.9.1 installed, and it is working, with some very basic rules.
I am trying to make a POST request that includes some header information, but doesn't have anything in the request body (the request is to an API endpoint which is being protected by mod_security, and that endpoint requires a POST without the request body). A POST that doesn't require a body is valid, per the following: Are PUT and POST requests required/expected to have a request body?
mod_security is blocking the request because it seems that it can't parse/format the body (likely because it doesn't exist).
How can I amend the rules to permit a POST without a body, but otherwise act as normal if the body does exist.
The specific rule that is being triggered is:
SecRule REQBODY_ERROR "!#eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:415,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
The error is:
[Fri Jul 08 10:32:32.901230 2016] [:error] [pid 7697] [client 10.0.2.2:57442] [client 10.0.2.2] ModSecurity: JSON parser error: parse error: premature EOF\n [hostname "example.com"] [uri "/api/v1/logout"] [unique_id "V377qH8AAQEAAB4RU6cAAAAD"]
[Fri Jul 08 10:32:32.901555 2016] [:error] [pid 7697] [client 10.0.2.2:57442] [client 10.0.2.2] ModSecurity: Access denied with code 415 (phase 2). Match of "eq 0" against "REQBODY_ERROR" required. [file "/etc/modsecurity/modsecurity.conf"] [line "61"] [id "200002"] [msg "Failed to parse request body."] [data "JSON parser error: parse error: premature EOF\\x0a"] [severity "CRITICAL"] [hostname "example.com"] [uri "/api/v1/logout"] [unique_id "V377qH8AAQEAAB4RU6cAAAAD"]
Or, should I simply not send a Content-Type HTTP header in order to get mod_security to parse the body (although I'd prefer to enforce that all POST requests always have a defined Content-Type)?
I've made a gist of the full modsecurity.conf that is being used (which is a basic example with two extra rules for filtering Content-Types).
You can disable body access for a request with zero body length:
SecRule REQUEST_BODY_LENGTH "#eq 0" "id:12345,phase:1,nolog,ctl:requestBodyAccess=off"
Or if you only want to do this on a certain URL then use a chained rule like this:
SecRule REQUEST_URI /my/weird/api "phase:1,id:12346,nolog,chain"
SecRule REQUEST_BODY_LENGTH "#eq 0" "ctl:requestBodyAccess=off"

Whitelisting JSON ARGS_NAMES

I could use some advice on whitelisting JSON ARGS_NAMES that modsecurity seems to complain about. I'm not sure how to properly specify the ARGS_NAMES for a JSON Request. My app uses JSON heavily, so there are a few of these alerts for different style requests.
The following alert is triggered by a POST request (sign-in/authentication) to my backend application:
2015-08-06T23:02:21.09022 [Thu Aug 06 23:02:21.090206 2015] [:error] [pid > 18099:tid 140155981653760] [client 192.168.216.16] ModSecurity: Warning. > Pattern match "(?i:(?:union\\s*?(?:all|distinct|[(!#]?)?\\s?[([]? \\s?select\\s+)|(?:\\w+\\s+like\\s+> [\"'\\xc2\\xb4\\xe2\\x80\\x99\\xe2\\x80\\x98])|(?:like\\\\s*? [\\"'\xc2\xb4\xe2\x80\x99\xe2\x80\x98]\\%)|(?: [\"'\\xc2\\xb4\\xe2\\x80\\x99\\xe2\\x80\\x98]\\\\s*?like\\\\W*? [\\"'\xc2\xb4 ..." at ARGS_NAMES: {"username":"userid2","password":"blahblah"}. [file "/etc/apache2/modsecurity-crs/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "223"] [id "981245"] [msg "Detects basic SQL authentication bypass attempts 2/3"] [data "Matched Data: \x22:\x22userid2\x22,\x22p found within ARGS_NAMES: {\x22username\x22:\x22userid2\x22,\x22password\x22:\x22blahblah\x22 }:{\x22username\x22:\x22userid2\x22,\x22password\x22:\x22blahblah\x22 }"] [severity "CRITICAL"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"][hostname "api.host.name"] [uri "/user-api/auth-service"] [unique_id "VcPnfQobAhEAAEazjWUAAABB"]
Here's another alert triggered by an AJAX update to a user's session data:
2015-07-22T22:02:03.61377 [Wed Jul 22 22:02:03.613737 2015] [:error] [pid > 14702:tid 140281273739008] [client 10.72.2.5] ModSecurity: Access denied > with code 403 (phase 2). Pattern match "(.*)" at TX:981257-Detects MySQL > comment-/space-obfuscated injections and backtick termination- OWASP_CRS/WEB_ATTACK/SQLI-ARGS_NAMES:{"data":{"categories": [{"uuid":"10009","name":"Books","folder":"School"}],"category_ids": ["188"],"transaction_ids":["ed529b9f47ee-ab23-5b98-4404-d59a86b9","ed529b9f47ee-ab23-5b98-4404-d59a86b9","ed529b9f47ee-ab23-5b98-4404-d59a86b9"]}}. [file "/etc/apache2/modsecurity-crs/activated_rules/modsecurity_crs_49_inbound_blocking.conf"] [line "26"][id "981176"] [msg "Inbound Anomaly Score Exceeded (Total Score: 20, SQLi=4, XSS=0): Last Matched Message: 981243-Detects classic SQL injection probings 2/2"] [data "Last Matched Data: ,\x22name\x22:"] [hostname "host.name.com"] [uri "/new/data"] [unique_id "VbAS2wobA80AADluSjYAAADw"]
How can I create a whitelist for "ARGS_NAMES:{"username[..]" or "ARGS_NAMES:{data[..]"? When I try to whitelist with regex, I wind up with a rule like this:
SecRule ARGS_NAMES:"({\"(data)\":)(({\"[a-z_]+\":).)" "(.)" "id:308,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=.;ARGS_NAMES:({\"(data)\":)(({\"[a-z_]+\":).)"
I believe this works unless PCRE limits exceeded, from testing. Is there an easier way to do this for JSON arguments?
Here's another method I tried in an earlier iteration of my whitelists:
SecRule ARGS:data.transaction_ids "(([a-z0-9-]))" "id:206,phase:2,nolog,pass,ctl:ruleRemoveTargetByTag=.;ARGS:data.transaction_ids,ctl:ruleRemoveTargetById=960024;ARGS:data.transaction_ids"
To the best of my knowledge this works, but I want to be able to whitelist any request that uses the "{data:" JSON format within the request body. I want to verify the correct method of whitelisting JSON arguments before I go in for another round of testing.
What am I missing here?

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 ?