Modsecurity - REQUEST_URI allow rule is not working - mod-security

We have following rules that are not working and we wanted to white list this warning ( in event viewer ), which contains "testinguri" in URI.
SecRule REQUEST_URI "#contains testinguri\?op\=message" "id:200006,phase:1,nolog,allow,ctl:ruleEngine=DetectionOnly,msg:'Test 1'"
SecRule REQUEST_URI "#beginsWith /en-us/testinguri?op=message" "id:200007,phase:1,nolog,allow,ctl:ruleEngine=DetectionOnly,msg:'Test 2'"
SecRule REQUEST_URI "^/en-us/testinguri?op=message.*" "id:200008,phase:1,nolog,allow,ctl:ruleEngine=DetectionOnly,msg:'Test 3'"
SecRule REQUEST_URI "#contains testinguri" "id:200009,phase:1,nolog,allow,ctl:ruleEngine=DetectionOnly,msg:'Test 4'"
Above rules are for same purpose but we put them if any version of the rule works but no luck.
Below is the warning in the event viewer and we want to allow the URI that have "testinguri" in it. It is running in Detection mode right now.
ModSecurity: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "C:\Program Files\ModSecurity IIS\owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "86"]
[id "980130"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=5,PHPI=0,HTTP=0,SESS=0): Remote Command Execution: Windows Command Injection; individual paranoia level scores: 5, 0, 0, 0"] [tag "event-correlation"] [hostname "computerName"] [uri "/en-us/testinguri?op=message&to=FULL URI..."] [unique_id "454534234234234"]
Can you please help on this. Thanks.

We were able to figure it out. So created a conf file test.conf and put the rules in that that we wanted to white list.
Then in the modsecurity_iis.conf file added this files reference at last.
This works for us. Hope this will help someone. Thanks.

Related

How to disable JSON format and send only the log message to Sumologic with Fluentbit?

We are using Fluentbit as as Sidecar container in our ECS fargate Cluster which is running a dotnet application, initially we faced the issue of fluentbit sending the logs in multiline and we solved it using Fluentbit Multilne feature. Now the logs are being sent to Sumologic in Multiple however it is being sent as Json format whereas we just want fluentbit send only the raw log
Logs are currently
{
date:1675120653.269619,
container_id:"xvgbertytyuuyuyu",
container_name:"XXXXXXXXXX",
source:"stdout",
log:"2023-01-30 23:17:33.269Z DEBUG [.NET ThreadPool Worker] Connection.ManagedDbConnection - ComponentInstanceEntityAsync - Executing stored proc: dbo.prcGetComponentInstance"
}
We want only the line
2023-01-30 23:17:33.269Z DEBUG [.NET ThreadPool Worker] Connection.ManagedDbConnection - ComponentInstanceEntityAsync - Executing stored proc: dbo.prcGetComponentInstance
You need to modify Fluent Bit configuration to have the following filters and output configuration:
fluent.conf:
## prepare headers for Sumo Logic
[FILTER]
Name record_modifier
Match *
Record headers.content-type text/plain
## Set headers as headers attribute
[FILTER]
Name nest
Match *
Operation nest
Wildcard headers.*
Nest_under headers
Remove_prefix headers.
[OUTPUT]
Name http
...
# use log key as body
body_key $log
# use headers key as headers
headers_key $headers
That way, you are going to craft HTTP request manually. This is going to send request per log, which is not necessary a good idea. In order to mitigate that you can add the following parser and use it (flush_timeout may need an adjustment):
parsers.conf
# merge everything as one big log
[MULTILINE_PARSER]
name multiline-all
type regex
flush_timeout 500
#
# Regex rules for multiline parsing
# ---------------------------------
#
# configuration hints:
#
# - first state always has the name: start_state
# - every field in the rule must be inside double quotes
#
# rules | state name | regex pattern | next state
# ------|---------------|--------------------------------------------
rule "start_state" ".*" "cont"
rule "cont" ".*" "cont"
fluent.conf:
[INPUT]
name tail
...
multiline.parser multiline-all

How to limit this modsecurity rule to one file?

I have this rule bellow, and I'd like to limit for only wp-login.php files. Is it possible?
SecRule REQUEST_HEADERS:User-Agent "#contains python-requests" "id:1000000,t:none,t:lowercase,deny,nolog,msg:'BAD BOT - Detected and Blocked. '"
Use chained rules:
SecRule REQUEST_URI "wp-admin.php" "chain,id:1000000,t:none,t:lowercase,deny,nolog,msg:'BAD BOT - Detected and Blocked. '"
SecRule REQUEST_HEADERS:User-Agent "#contains python-requests" ",t:none,t:lowercase"

how to warn instead of block invalid quoting in modsecurity

Ive got an issue with modsecurity and Im wondering if anyone can help. I'm running into an issue with uploading files to my application, anytime the file in question has a quote in the filename. Eventually I will do client side validation which will alert a user to a quote in the filename they are trying to upload and tell them to rename it, but for now I need to amend my modsecurity settings to ignore that particular check.
The modsecurity rule is:
SecRule MULTIPART_STRICT_ERROR "!#eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart request body \
failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_SEMICOLON_MISSING}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
IH %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
The error Im getting is:
[2016-10-11T16:08:06.8336+01:00] [OHS] [ERROR:32] [OHS-9999] [blah.c] [host_id: blah-web-kc1d] [host_addr: 1.2.3.4] [tid: 1724] [user: SYSTEM] [ecid: 00ibIu6vODDF4ETzA8m3SD0000_^001B9G] [rid: 0] [VirtualHost: main] [client 1.2.3.4] ModSecurity: Access denied with code 403 (phase 2). Match of "eq 0" against "MULTIPART_STRICT_ERROR" required. [file "E:/blah/security/<span class="skimlinks-unlinked">blah_base_rules.conf</span>"] [line "65"] [msg "Multipart request body failed strict validation: PE 0, BQ 0, BW 0, DB 0, DA 0, HF 0, LF 0, SM , IQ 1, IH 0, IH 0"] [hostname "<span class="skimlinks-unlinked">www.dev.uk</span>"] [uri "/pls/dev/blah_details_form.process_blah"] [unique_id "ZOMG!<span class="skimlinks-unlinked">ROFL.TL;DR</span>"]
IQ 1 suggests its the invalid quoting which makes sense. How do I tell modsecurity, to not block when it detects invalid quoting, without disabling the rest of the rule?
Thanks
P.S. I know allowing quotes in a filename potentially introduces SQL injection, but we aren't worried about that for reasons I can't go into.
Just replace the current rule (which checks the overall MULTIPART_STRICT_ERROR variable) with separate rules for each individual variable instead, changing the deny to a warn for the one variable you don't want to deny:
SecRule REQBODY_PROCESSOR_ERROR "!#eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart request body \ failed strict
validation: \ PE %{REQBODY_PROCESSOR_ERROR}'"
SecRule MULTIPART_BOUNDARY_QUOTED "!#eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart request body \ failed strict
validation: \ BQ %{MULTIPART_BOUNDARY_QUOTED}'"
...etc.
SecRule MULTIPART_INVALID_QUOTING "!#eq 0" \
"phase:2,t:none,log,warn,msg:'Multipart request body \ failed strict
validation: \ IQ %{MULTIPART_INVALID_QUOTING}'"
SecRule MULTIPART_INVALID_HEADER_FOLDING "!#eq 0" \
"phase:2,t:none,log,deny,msg:'Multipart request body \ failed strict
validation: \ IH %{MULTIPART_INVALID_HEADER_FOLDING}'"
...etc.
Note newer versions of ModSecurity (since 2.7) require a unique id so if your rule has an id which you've not shown in your question then make sure you make it unique when creating the many rules.
Finally it is also possible to check all the variables in one rule or have the rules sum up the values (or have them as part of one large chained rule where values are similarly summed up) and then check sum = 0 but separate rules is probably just simpler and easier to follow in future.
I fixed this by renaming the file name to upload as it contains some unrecognized pattern.
How do I resolve the issue?
Simply put, rename the file to remove the offending special character from the file name
or (disable this security rule in /etc/{path}/mod_security.conf by commenting the line " SecRule MULTIPART_STRICT_ERROR "!#eq 0" \" or by .htaccess file - NOT RECOMMENDED AT ALL)
How is this error caused?
This error is caused by mod_security blocking a potentially malicious upload. While it may be completely harmless, mod_security has no way of knowing if it is harmless or not.
Typically, the content in question is a file being uploaded which contains a special character such as a single or double quote within the file name which is often used by attackers to inject malicious scripts into websites.

HAProxy 1.6+: rewrite host based on path

I'm trying to redirect all requested of type:
static.domain.com/site1/resource.jpg
static.domain.com/site1/resource2.js
static.domain.com/site2/resource3.gif
static.domain.com/site2/someDir/resource4.txt
to
site1.domain.com/resource.jpg
site1.domain.com/resource2.js
site2.domain.com/resource3.gif
site2.domain.com/someDir/resource4.txt
Basically, if the host is static.domain.com:
New subdomain is based on the the first part of the original path, with same TLD
New path is the original path not including the first part
I am pretty sure regexps can solve this, just not sure how to modify one header based on another..
At first I thought this might work:
# Detect hosts of the format static.*
acl host_static hdr_beg(host) -i static.
# Style using reqirep
# -------------
# Replace "static.domain.com" with "someFolder.domain.com" if the host is static.* and the path has at least two / symbols
# This causes: static.domain.com ===> whatever3.domain.com
#reqirep ^([^\ :]*\ /)([^/]+)(/.*\n)(^(?:[a-zA-Z0-9()\-=\*\.\?;,+\/&_]+:\ .+\n)+)*Host:\ static\.([^/]+?)$ \1\2\3\4Host:\ \2.\5 if host_static
#
# Replace "/someFolder/" with "/" at the beginning of any request path, if the host is static.*
# This causes: /whatever3/another/long/path ===> /another/long/path
#reqirep ^([^\ :]*)\ /[^/]+/(.*) \1\ /\2 if host_static
#---------------
but it doesn't work as expected. The regexp works properly in controlled tests, but not in haproxy itself. Probably an issue of directive processing and execution order. (perhaps the modification of the request path screws the first regexp?)
I then tried this:
# Style using set-var, set-path etc
#---------------
#http-request set-var(req.first_path_part) path,field(2,/) if host_static
#http-request set-var(req.last_host_part) hdr(host),regsub(^static\.,) if host_static
#http-request replace-header Host .* %[var(req.first_path_part)].%[var(req.last_host_part)] if host_static
#http-request set-path %[path,regsub(^/.*?/,/)] if host_static
#---------------
Once again, it almost works, but for some reason the host doesn't get replaced properly.
Since this was only used by the QA env, and the behaviour is different from Production anyways (static.*, in my case, would point to a CDN), I decided this is a sufficient solution for now:
# New style, using set-var and redirection.
#---------------
http-request set-var(req.first_path_part) path,field(2,/) if host_static
http-request set-var(req.last_host_part) hdr(host),regsub(^static\.,) if host_static
http-request redirect location https://%[var(req.first_path_part)].%[var(req.last_host_part)]%[path,regsub(^/.*?/,/)] code 302 if host_static
#---------------
I'm not sure how HAProxy works, but I can help you with the regex.
Try: ^static\.([^/]+)/([^/]+)/(.*)$
Your new URL will be \2.\1/\3.
Note that you may need to escape the /s in the regex (which would make it \/).

Apache 2.4 setenvif dontlog pingdom.com

Many of webmasters use pingdom.com as a monitoring ping service.
But the problem is that /httpd/access_log is full of
208.64.28.194 - - [06/Aug/2015:12:20:22 -0500] "GET / HTTP/1.1" 200 2917 "-" "Pingdom.com_bot_version_1.4_(http://www.pingdom.com/)"
I set
CustomLog "logs/access_log" combined env=!dontlog
and tried to get rid of it using variations like
SetEnvIf Remote_Host "^pingdom\.com$" dontlog
SetEnvIFNoCase Remote_Host "pingdom.com$" dontlog
SetEnvIfNoCase Referer "www\.pingdom\.com" dontlog
SetEnvIFNoCase Host "^pingdom.com$" dontlog
but still no a success with any of them - so thanks for any else hint to try.
I'll put my comment here as answer so anyone will find this easier.
Since one can see from the log file, the host name is not Pingdom.com but a part of the user agent string.
Solutions to try:
First be sure you have enabled the setenvif-module. Write the command
sudo apache2ctl -M | grep setenv
It should return something like "setenvif_module (shared)"
Then you can try setting by remote address
SetEnvIf Remote_Addr "208\.64\.28\.194$" dontlog
The final working solution is this, dont log if the user agent string contains Pingdom string:
SetEnvIfNoCase User-Agent "^Pingdom" dontlog
Edit: enhanced some parts of the answer.