owasp-modsecurity / owasp-modsecurity/ModSecurity-nginx
ModSecurity False Positive with respect to logging in ModSec audit + NGX error logs due to NGINX behavior with error_page directive
Nobody has claimed this yet.
- Dominant language
- Perl
- Stars
- 1.9k
- Forks
- 312
- PR merge metrics
- No merged PRs in 30d
Description
Decided to pull out my comment to a separate issue since its unrelated to the other issue I raised originally:
I was trying to limit the relevant to 400's and 403's for capturing blocked transactions by ModSecurity:
SecAuditLogRelevantStatus "^(?:4((00)|(03)))"
Yet I see the audit log in RelevantOnly mode still also capturing 504 status messages as well for some reason.
SO this one is an interesting case. I am 100% sure on why 504's were making it into the audit logs even through its regex was set to 400's and 403's because I saw odd behavior in other apps too that hook into NGX with logged values not matching what the client really sent.
Firstly take a gander here(the app we run on nginx + openresty), leveraging the error_page directive:
https://github.com/Kong/kong/blob/3.7.0/kong/templates/nginx_kong.lua#L94
Then take a gander here at how Kong or OpenResty can be patched for such situations:
Kong/kong#5073
openresty/openresty#396
So what happens is when NGINX does an internal redirect via error_page, and the CTX of the client HTTP METHOD gets reset to GET always, so the NGINX ModSec audit/error logs are thinking REAL 504 timeout transactions are now a GET with a HTTP body(client sends req body) in the audit log logic(The Method the client actually used in the originating request was a POST), so it saves an blocked error log w 403 in the audit log file section H, for the transaction BUT the real transaction was a 504 and it was presented to the client as a 504, just internal logging and record keeping Modsecurity-nginx is not handling these scenarios where error_page directive gets used by folks leveraging the NGINX web server.
The fix could easily be if yall added a custom mod security http method variable to the tx context in the pre-access phase taking the original r->method to track the Method before the error_page directive internal redirect and read that custom mod sec http method variable after in the audit/error log phase logic after the redirect has occurred as the source of truth rather than the current ngx contexts r->method(which would be reset to always be GET at that time). Will save on the noisy invalid logs.
Ex of current behavior(Upstream times out in reverse proxy call, we hit error_page directive, http method gets reset to GET internally, triggering ModSec to log this tx as a block in error + audit log incorrectly when it was really just a harmless timeout):
2020/02/20 07:47:40 [error] 71#0: *65758 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.96.16.138, server: kong, request: "POST /api/memleak HTTP/1.1", upstream: "http://10.86.228.171:9393/ ", host: "gateway.company.com"
2020/02/20 07:47:40 [error] 71#0: *65758 [client 10.96.16.138] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator
Ge' with parameter5' against variableTX:ANOMALY_SCORE' (Value:5' ) [file "/usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "79"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "10.129.45.91"] [uri "/api/memleak"] [unique_id "158218486097.459274"] ...
ModSecurity-nginx: latest master branch
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the reported POST timeout with NGINX's error_page directive, ModSecurity audit logging in RelevantOnly mode, and the stated SecAuditLogRelevantStatus pattern. Inspect the connector's pre-access handling and audit/error-log phases; done means the original transaction method and status remain authoritative after the internal redirect, without spurious audit or error-log entries.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- nginx
- Domain
- security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100