I have configured modsecurity-nginx connector on Kubernetes Nginx Controller.
Currently, my objective to use ModSecurity WAF is to implemented in DetectionOnly
mode as I don’t want to start blocking everything right away. So to fulfil that I used below configuration in my Controller ConfigMaps.
enable-modsecurity: "true"
modsecurity-snippet: |
SecRuleEngine DetectionOnly
SecAuditEngine On
SecAuditLogParts ABIJDEFHZ
SecAuditLogFormat JSON
SecAuditLogType Serial
SecAuditLog /dev/stdout
To test this, I tried SQL injection attack in which I inserted a SQL query from client to my test application. But ModSecurity did not give any warning or any useful information in the logs which tells that an SQL query was inserted in the application. Below is the request which i sent and got logs respectively :
$ curl -ks -o /dev/null -w ‘%{http_code}’ “https://test-ingress-nginx.example.com/foo?username=1'%20or%20'1'%20=%20'”
Output : 404
Logs :
----
{“transaction”:{“client_ip”:“192.xxx.xxx.xx",“time_stamp”:“Tue Feb 16 07:44:10 2021",“server_id”:“995f188ad543e6fcbcdbfb4c7a2c67327xxxxx",“client_port”:59455,“host_ip”:“10.x.xxx.xxx”,“host_port”:443,“unique_id”:“161346145098.924xxx",“request”:{“method”:“GET”,“http_version”:2.0,“uri”:“/foo?username=1'%20or%20'1'%20=%20'“,”headers”:{“host”:“test-ingress-nginx.example.com”,“user-agent”:“curl/7.64.1",“accept”:“*/*“}},“response”:{“body”:“<!DOCTYPE HTML PUBLIC “-//IETF//DTD HTML 2.0//EN“>n<html><head>n<title>404 Not Found</title>n</head><body>n<h1>Not Found</h1>n<p>The requested URL /foo was not found on this server.</p>n<hr>n<address>Apache/2.4.25 (Debian) Server at test-ingress-nginx.example.com Port 80</address>n</body></html>n”,“http_code”:404,“headers”:{“Server”:“”,“Server”:“”,“Date”:“Tue, 16 Feb 2021 07:44:10 GMT”,“Content-Length”:“306”,“Content-Type”:“text/html; charset=iso-8859-1”,“Connection”:“close”,“Strict-Transport-Security”:“max-age=15724800; includeSubDomains”}},“producer”:{“modsecurity”:“ModSecurity v3.0.4 (Linux)“,”connector”:“ModSecurity-nginx v1.0.1”,“secrules_engine”:“DetectionOnly”,“components”:[]},“messages”:[]}}
And If I change SecRuleEngine DetectionOnly
to SecRuleEngine On
then the error code changes and the logs shows why the request got blocked :
$ curl -ks -o /dev/null -w ‘%{http_code}’ “https://test-ingress-nginx.example.com/foo?username=1'%20or%20'1'%20=%20'”
Output : 403
Logs :
----
2021/02/16 07:35:11 [error] 8100#8100: *25411553 [client 192.xxx.xxx.xx] ModSecurity: Access denied with code 403 (phase 2). Matched “Operator `Ge’ with parameter `5' against variable `TX:ANOMALY_SCORE’ (Value: `5' ) [file “/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf”] [line “80"] [id “949110”] [rev “”] [msg “Inbound Anomaly Score Exceeded (Total Score: 5)“] [data “”] [severity “2"] [ver “OWASP_CRS/3.3.0”] [maturity “0"] [accuracy “0”] [tag “application-multi”] [tag “language-multi”] [tag “platform-multi”] [tag “attack-generic”] [hostname “10.x.xxx.xxx"] [uri “/foo”] [unique_id “16134609114.611xxx"] [ref “”], client: 192.xxx.xx.xx, server: test-ingress-nginx.example.com, request: “GET /foo?username=1'%20or%20'1'%20=%20' HTTP/2.0", host: “test-ingress-nginx.example.com”
Issue : Is there a way I can get some useful information in the ModSecurity Logs, when I enable ModSecurity in Detection Only
Mode, so that I can identify what kind of requests/threat are coming to my application and hence start writing Blocking rule for them.
2
Answers
I think you should get another related log:
For example, to see modsecurity logs in my case are here /var/log/modsec_audit.log
If you check this log /var/log/audit//20220119/20220119-1521/20220119-152155-164260571591.117736, you will see the explanation:
Core Rule Set Dev on Duty here. In your log output for 403 I see that you have ModSecurity configured with the OWASP Core Rule Set.
Your ModSecurity configuration seems to be correct, you have the correct
SecAuditLogParts
configured.When I test this with the official CRS Docker container with exactly the same ModSecurity configuration I get the following output:
The difference between my and your output is:
In my output I see the components: "OWASP_CRS/3.4.0-dev""
And the messages array contains two messages: one is the violated CRS rule 942100 and the blocking rule 949110.
As we see in the response from today, which shows a ModSecurity AuditLog in
SecAuditLogFormat Native
instead ofSecAuditLogFormat JSON
, the violated rules should be listed inSecAuditLogParts
partH
.To confirm this I tested it in my environment and I can switch off the messages part with exactly this part
H
.So I investigated further and I found some ModSecurity issues related to your problem.
These do not 1:1 explain your problem.
A difference I see between the CRS rules is:
The SQL injection rule that is triggered by your curl test is
942100
which has actionblock
(not logged): https://github.com/coreruleset/coreruleset/blob/v3.4/dev/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf#L46The blocking evaluation rule that blocks the request with id
949110
has actiondeny
: https://github.com/coreruleset/coreruleset/blob/v3.4/dev/rules/REQUEST-949-BLOCKING-EVALUATION.conf#L139.As I said above this does not 1:1 explain your problem. But I suggest that you upgrade to the latest versions and test it again. Your post is 11 months old and the problem could have been resolved in the meantime because we see some ModSecurity issues and pull request related to this problem.