owasp-modsecurity / ModSecurity

ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx. It has a robust event-based programming language which provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analysis.
https://www.modsecurity.org
Apache License 2.0
8.25k stars 1.61k forks source link

Malicious POST request logged as GET request in audit logs #3302

Closed Dr-Lazarus-V2 closed 11 hours ago

Dr-Lazarus-V2 commented 12 hours ago

Describe the bug

I have created a custom rule to detect the word confidential in the REQUEST_BODY. If the word is detected, the action to undertake is deny. However when I make this POST request the request is logged as a GET in the audit logs.

Here is the custom rule:

SecRule REQUEST_BODY "@rx (?i)(\b|\W*)confidential" "id:1, phase:2, deny, log, t:none, msg:'UNAUTHORIZED DATA ACCESS'"

Logs and dumps Audit Logs

{
    "transaction": {
        "client_ip": "10.103.253.240",
        "time_stamp": "Thu Nov 14 05:08:27 2024",
        "server_id": "327c12d21520fbed95c8764ad076e59b7ea5d783",
        "client_port": 51501,
        "host_ip": "192.168.32.3",
        "host_port": 8080,
        "unique_id": "8f198db9483934603d69ce8654326042",
        "request": {
            "method": "GET",
            "http_version": 1.1,
            "uri": "/check",
            "headers": {
                "Content-Type": "application/json",
                "User-Agent": "PostmanRuntime/7.42.0",
                "Postman-Token": "6936971e-b447-4419-8f95-262f0a590386",
                "Accept": "*/*",
                "Host": "weborion.licensing.portal",
                "Accept-Encoding": "gzip, deflate, br",
                "Connection": "keep-alive",
                "Content-Length": "21"
            }
        },
        "response": {
            "http_code": 403,
            "headers": {
                "Server": "nginx/1.27.2",
                "Date": "Thu, 14 Nov 2024 05:08:27 GMT",
                "Content-Type": "text/html",
                "Connection": "keep-alive",
                "ETag": "\"66dfdff2-93d6\""
            }
        },
        "producer": {
            "modsecurity": "ModSecurity v3.0.13 (Linux)",
            "connector": "ModSecurity-nginx v1.0.3",
            "secrules_engine": "Enabled",
            "components": [
                "OWASP_CRS/4.8.0\""
            ]
        },
        "messages": [
            {
                "message": "GET or HEAD Request with Body Content",
                "details": {
                    "match": "Matched \"Operator `Rx' with parameter `^0?$' against variable `REQUEST_HEADERS:Content-Length' (Value: `21' )",
                    "reference": "o0,3v0,3v255,2",
                    "ruleId": "920170",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf",
                    "lineNumber": "171",
                    "data": "21",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "platform-multi",
                        "attack-protocol",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/210/272"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "UNAUTHORIZED DATA ACCESS",
                "details": {
                    "match": "Matched \"Operator `Rx' with parameter `(?i)(\\b|\\W*)confidential' against variable `REQUEST_BODY' (Value: `{\"confidential\":true}' )",
                    "reference": "o0,14o0,2v258,21",
                    "ruleId": "1",
                    "file": "/var/opt/modsecurity.d/custom-ruleset/TestRukeset/TestRukeset-RULES.conf",
                    "lineNumber": "1",
                    "data": "",
                    "severity": "0",
                    "ver": "",
                    "rev": "",
                    "tags": [],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "Inbound Score: 5 Outbound Score: 0",
                "details": {
                    "match": "",
                    "reference": "",
                    "ruleId": "980145",
                    "file": "/var/opt/modsecurity.d/owasp-crs/weborion.licensing.portal.crs_setup.conf",
                    "lineNumber": "40",
                    "data": "",
                    "severity": "0",
                    "ver": "",
                    "rev": "",
                    "tags": [],
                    "maturity": "0",
                    "accuracy": "0"
                }
            }
        ]
    }
}

Debug Logs (Level 9) Modsecurity-Debug-Logs-Level-9.txt

A more closer view:

[8f198db9483934603d69ce8654326042] [/check] [4] (Rule: 911100) Executing operator "Within" with param "GET HEAD POST OPTIONS" Was: "" against REQUEST_METHOD.
[8f198db9483934603d69ce8654326042] [/check] [9] Target value: "POST" (Variable: REQUEST_METHOD)
[8f198db9483934603d69ce8654326042] [/check] [4] Rule returned 0.
[8f198db9483934603d69ce8654326042] [/check] [9] Matched vars cleaned
[8f198db9483934603d69ce8654326042] [/check] [9] Matched vars cleaned.
[8f198db9483934603d69ce8654326042] [/check] [4] (Rule: 911100) Executing operator "Within" with param "GET HEAD POST OPTIONS" Was: "" against REQUEST_METHOD.
[8f198db9483934603d69ce8654326042] [/check] [9] Target value: "GET" (Variable: REQUEST_METHOD)
[8f198db9483934603d69ce8654326042] [/check] [4] Rule returned 0.
[8f198db9483934603d69ce8654326042] [/check] [9] Matched vars cleaned.

In the logs above you can see that for the same unique_id 8f198db9483934603d69ce8654326042, the REQUEST_METHOD variable value changes from POST to GET

Error Logs:

2024/11/14 05:08:27 [error] 93#93: *16 [client 10.103.253.240] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Rx' with parameter `(?i)(\b|\W*)confidential' against variable `REQUEST_BODY' (Value: `{"confidential":true}' ) [file "/var/opt/modsecurity.d/custom-ruleset/TestRukeset/TestRukeset-RULES.conf"] [line "1"] [id "1"] [rev ""] [msg "UNAUTHORIZED DATA ACCESS"] [data ""] [severity "0"] [ver ""] [maturity "0"] [accuracy "0"] [hostname "192.168.32.3"] [uri "/check"] [unique_id "8f198db9483934603d69ce8654326042"] [ref "o0,14o0,2v259,21"], client: 10.103.253.240, server: weborion.licensing.portal, request: "POST /check HTTP/1.1", host: "weborion.licensing.portal"

2024/11/14 05:08:27 [error] 93#93: *16 [client 10.103.253.240] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Rx' with parameter `(?i)(\b|\W*)confidential' against variable `REQUEST_BODY' (Value: `{"confidential":true}' ) [file "/var/opt/modsecurity.d/custom-ruleset/TestRukeset/TestRukeset-RULES.conf"] [line "1"] [id "1"] [rev ""] [msg "UNAUTHORIZED DATA ACCESS"] [data ""] [severity "0"] [ver ""] [maturity "0"] [accuracy "0"] [hostname "192.168.32.3"] [uri "/check"] [unique_id "8f198db9483934603d69ce8654326042"] [ref "o0,14o0,2v258,21"], client: 10.103.253.240, server: weborion.licensing.portal, request: "POST /check HTTP/1.1", host: "weborion.licensing.portal"

In the error log the same request gets logged twice, it gets logged as POST request.

To Reproduce

  1. Setup an POST endpoint in the server/webApp protected by the WAF.
  2. Add the custom rule.
  3. Modsecurity Configuration:

SecRuleEngine On

SecRequestBodyAccess on SecRule REQUEST_HEADERS:Content-Type "^(?:application(?:/soap+|/)|text/)xml" \ "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" SecRule REQUEST_HEADERS:Content-Type "^application/json" \ "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" SecRequestBodyLimit 10485760 SecRequestBodyNoFilesLimit 1048576 SecRequestBodyLimitAction ProcessPartial SecRequestBodyJsonDepthLimit 512 SecArgumentsLimit 1000

SecRule &ARGS "@ge 1000" \ "id:'200007', phase:2,t:none,log,deny,status:400,msg:'Failed to fully parse request body due to large argument count',severity:2"

SecRule REQBODY_ERROR "!@eq 0" \ "id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"

SecRule MULTIPART_STRICT_ERROR "!@eq 0" \ "id:'200003',phase:2,t:none,log,deny,status:400, \ 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_MISSING_SEMICOLON}, \ IQ %{MULTIPART_INVALID_QUOTING}, \ IP %{MULTIPART_INVALID_PART}, \ IH %{MULTIPART_INVALID_HEADER_FOLDING}, \ FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"

SecPcreMatchLimit 100000 SecPcreMatchLimitRecursion 100000 SecRule TX:/^MSC_/ "!@streq 0" \ "id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"

SecResponseBodyAccess on SecResponseBodyMimeType text/plain text/html text/xml application/JSON SecResponseBodyLimit 537600 SecResponseBodyLimitAction Reject

SecTmpDir /tmp/ SecDataDir /tmp/

SecAuditEngine On SecAuditLogType Serial SecAuditLogRelevantStatus "^(?:5|4(?!04))" SecAuditLog /var/log/modsec_logs/modsec_audit_weborion.licensing.portal.log SecAuditLogFormat JSON SecAuditLogParts ABFHZ

SecArgumentSeparator & SecCookieFormat 0 SecUnicodeMapFile unicode.mapping 20127 SecStatusEngine Off

SecGeoLookupDb /var/GeoLite2-Country/GeoLite2-Country.mmdb

SecDebugLog /var/log/modsec_logs/modsec_debug.log SecDebugLogLevel 9

4. Make a curl request to the endpoint

**Curl Command**
`curl --location 'http://<domain>/check' \
--header 'Content-Type: application/json' \
--data '{"confidential":true}'`

**Expected behavior**

The audit logs should log the request as `POST` and not `GET`.

**Server (please complete the following information):**
 - ModSecurity version (and connector): 3.0.13
 - Modsecurity-Nginx Connector: v1.0.3
 - CRS Version: 4.8.0
 - WebServer: Nginx Version: 1.27.2
 - OS (and distro): Ubuntu 22.04

**Rule Set (please complete the following information):**
 - Running any public or commercial rule set? OWASP CRS
 - What is the version number? 4.8.0

**Additional context**
I can see that the transaction starts again when the custom rule is triggered.

[8f198db9483934603d69ce8654326042] [/check] [4] (Rule: 1) Executing operator "Rx" with param "(?i)(\b|\W*)confidential" against REQUEST_BODY. [8f198db9483934603d69ce8654326042] [/check] [9] Target value: "{"confidential":true}" (Variable: REQUEST_BODY) [8f198db9483934603d69ce8654326042] [/check] [9] Matched vars updated. [8f198db9483934603d69ce8654326042] [/check] [4] Rule returned 1. [8f198db9483934603d69ce8654326042] [/check] [9] Saving msg: UNAUTHORIZED DATA ACCESS [8f198db9483934603d69ce8654326042] [/check] [9] Running action: log [8f198db9483934603d69ce8654326042] [/check] [9] Saving transaction to logs [8f198db9483934603d69ce8654326042] [/check] [4] Running (disruptive) action: deny. [8f198db9483934603d69ce8654326042] [/check] [8] Running action deny [8f198db9483934603d69ce8654326042] [/check] [8] Skipping this phase as this request was already intercepted. [8f198db9483934603d69ce8654326042] [] [4] Initializing transaction [8f198db9483934603d69ce8654326042] [] [4] Transaction context created. [8f198db9483934603d69ce8654326042] [] [4] Starting phase CONNECTION. (SecRules 0) [8f198db9483934603d69ce8654326042] [] [9] This phase consists of 29 rule(s). [8f198db9483934603d69ce8654326042] [] [4] Starting phase URI. (SecRules 0 + 1/2)



I am not sure if this is the expected behaviour from the backed. After this process it seems that the request goes through all the 4 phases again, however this time the `REQUEST_METHOD` becomes `GET`
Dr-Lazarus-V2 commented 12 hours ago

I have conducted a further investigation and can note that even a request which triggerers a CRS rule has the same issue.

curl -X POST http://weborion.licensing.portal/check \                        with lazarus@weborion-test-server at 05:41:12 AM
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=admin' OR '1'='1;--&password=<script>alert('XSS')</script>&cmd=;cat /etc/passwd;"
{
    "transaction": {
        "client_ip": "10.103.253.191",
        "time_stamp": "Thu Nov 14 05:41:12 2024",
        "server_id": "327c12d21520fbed95c8764ad076e59b7ea5d783",
        "client_port": 48752,
        "host_ip": "192.168.32.3",
        "host_port": 8080,
        "unique_id": "6e46a0dff39cbcc3e1f3a1d396afaa22",
        "request": {
            "method": "GET",
            "http_version": 1.1,
            "uri": "/check",
            "headers": {
                "Host": "weborion.licensing.portal",
                "User-Agent": "curl/7.81.0",
                "Accept": "*/*",
                "Content-Type": "application/x-www-form-urlencoded",
                "Content-Length": "89"
            }
        },
        "response": {
            "http_code": 403,
            "headers": {
                "Server": "nginx/1.27.2",
                "Date": "Thu, 14 Nov 2024 05:41:11 GMT",
                "Content-Type": "text/html",
                "Connection": "keep-alive",
                "ETag": "\"66dfdff2-93d6\""
            }
        },
        "producer": {
            "modsecurity": "ModSecurity v3.0.13 (Linux)",
            "connector": "ModSecurity-nginx v1.0.3",
            "secrules_engine": "Enabled",
            "components": [
                "OWASP_CRS/4.8.0\""
            ]
        },
        "messages": [
            {
                "message": "GET or HEAD Request with Body Content",
                "details": {
                    "match": "Matched \"Operator `Rx' with parameter `^0?$' against variable `REQUEST_HEADERS:Content-Length' (Value: `89' )",
                    "reference": "o0,3v0,3v152,2",
                    "ruleId": "920170",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf",
                    "lineNumber": "171",
                    "data": "89",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "platform-multi",
                        "attack-protocol",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/210/272"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "OS File Access Attempt",
                "details": {
                    "match": "Matched \"Operator `PmFromFile' with parameter `lfi-os-files.data' against variable `ARGS:cmd' (Value: `;cat /etc/passwd;' )",
                    "reference": "o6,10v228,17t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin",
                    "ruleId": "930120",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf",
                    "lineNumber": "97",
                    "data": "Matched Data: etc/passwd found within ARGS:cmd: ;cat /etc/passwd;",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "platform-multi",
                        "attack-lfi",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/255/153/126",
                        "PCI/6.5.4"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "Remote Command Execution: Unix Shell Code Found",
                "details": {
                    "match": "Matched \"Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:cmd' (Value: `;cat /etc/passwd;' )",
                    "reference": "o5,10v228,17t:cmdLine,t:normalizePath",
                    "ruleId": "932160",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf",
                    "lineNumber": "596",
                    "data": "Matched Data: etc/passwd found within ARGS:cmd:  cat/etc/passwd ",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-shell",
                        "platform-unix",
                        "attack-rce",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/152/248/88",
                        "PCI/6.5.2"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "XSS Attack Detected via libinjection",
                "details": {
                    "match": "detected XSS using libinjection.",
                    "reference": "v194,29t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls",
                    "ruleId": "941100",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf",
                    "lineNumber": "82",
                    "data": "Matched Data: XSS data found within ARGS:password: <script>alert('XSS')</script>",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "platform-multi",
                        "attack-xss",
                        "xss-perf-disable",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/152/242"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "XSS Filter - Category 1: Script Tag Vector",
                "details": {
                    "match": "Matched \"Operator `Rx' with parameter `(?i)<script[^>]*>[\\s\\S]*?' against variable `ARGS:password' (Value: `<script>alert('XSS')</script>' )",
                    "reference": "o0,8v194,29t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls",
                    "ruleId": "941110",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf",
                    "lineNumber": "108",
                    "data": "Matched Data: <script> found within ARGS:password: <script>alert('XSS')</script>",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "platform-multi",
                        "attack-xss",
                        "xss-perf-disable",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/152/242"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "NoScript XSS InjectionChecker: HTML Injection",
                "details": {
                    "match": "Matched \"Operator `Rx' with parameter `(?i)<[^0-9<>A-Z_a-z]*(?:[^\\s\\x0b\\\"'<>]*:)?[^0-9<>A-Z_a-z]*[^0-9A-Z_a-z]*?(?:s[^0-9A-Z_a-z]*?(?:c[^0-9A-Z_a-z]*?r[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?p[^0-9A-Z_a-z]*?t|t[^0-9A-Z_a-z]*?y[^0-9A-Z_a-z]*?l[^0-9A (4378 characters omitted)' against variable `ARGS:password' (Value: `<script>alert('XSS')</script>' )",
                    "reference": "o0,7v194,29t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls",
                    "ruleId": "941160",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf",
                    "lineNumber": "200",
                    "data": "Matched Data: <script found within ARGS:password: <script>alert('XSS')</script>",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "platform-multi",
                        "attack-xss",
                        "xss-perf-disable",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/152/242"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "Javascript method detected",
                "details": {
                    "match": "Matched \"Operator `Rx' with parameter `(?i)\\b(?:eval|set(?:timeout|interval)|new[\\s\\x0b]+Function|a(?:lert|tob)|btoa|prompt|confirm)[\\s\\x0b]*\\(' against variable `ARGS:password' (Value: `<script>alert('XSS')</script>' )",
                    "reference": "o8,6v194,29t:htmlEntityDecode,t:jsDecode",
                    "ruleId": "941390",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf",
                    "lineNumber": "713",
                    "data": "Matched Data: alert( found within ARGS:password: <script>alert('XSS')</script>",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "attack-xss",
                        "xss-perf-disable",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/152/242"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "SQL Injection Attack Detected via libinjection",
                "details": {
                    "match": "detected SQLi using libinjection.",
                    "reference": "v165,19",
                    "ruleId": "942100",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf",
                    "lineNumber": "46",
                    "data": "Matched Data: s&sos found within ARGS:username: admin' OR '1'='1;--",
                    "severity": "2",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "application-multi",
                        "language-multi",
                        "platform-multi",
                        "attack-sqli",
                        "paranoia-level/1",
                        "OWASP_CRS",
                        "capec/1000/152/248/66",
                        "PCI/6.5.2"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "Inbound Anomaly Score Exceeded (Total Score: 40)",
                "details": {
                    "match": "Matched \"Operator `Ge' with parameter `20' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `40' )",
                    "reference": "",
                    "ruleId": "949110",
                    "file": "/etc/modsecurity.d/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf",
                    "lineNumber": "222",
                    "data": "",
                    "severity": "0",
                    "ver": "OWASP_CRS/4.8.0",
                    "rev": "",
                    "tags": [
                        "anomaly-evaluation",
                        "OWASP_CRS"
                    ],
                    "maturity": "0",
                    "accuracy": "0"
                }
            },
            {
                "message": "Inbound Score: 40 Outbound Score: 0",
                "details": {
                    "match": "",
                    "reference": "",
                    "ruleId": "980145",
                    "file": "/var/opt/modsecurity.d/owasp-crs/weborion.licensing.portal.crs_setup.conf",
                    "lineNumber": "40",
                    "data": "",
                    "severity": "0",
                    "ver": "",
                    "rev": "",
                    "tags": [],
                    "maturity": "0",
                    "accuracy": "0"
                }
            }
        ]
    }
}

In the audit logs this is logged as a GET and not a POST.

Dr-Lazarus-V2 commented 11 hours ago

I believe this issue relates to the REQUEST_METHOD being reset on redirection: Issue

My Nginx configuration involves a redirect:

       error_page 403 /error.html;
       location = /error.html {
                ssi on;
                internal;
                auth_basic off;
                root /etc/nginx/template;
            }

There is a workaround metioned by @hator


I think I found one more way that might help.

It is to use a named location for the error page instead of a URL, like so:

error_page 403 @error;
location @error {
   ...
}
Then NGINX won't change the request method to GET and full audit log will appear with correct messages in part H.

If there is no need to change URI and method during internal redirection it is possible to pass error processing into a named location: [...]
(http://nginx.org/en/docs/http/ngx_http_core_module.html#error_page)

EDIT: I just noticed the reference to https://github.com/owasp-modsecurity/ModSecurity-nginx/issues/152#issuecomment-593259386 which seems to use the same solution (although in a little more complicated way)
Dr-Lazarus-V2 commented 11 hours ago

This issue seems to be a duplicate of another issue opened earlier in the Modsecurity-Nginx connector Issue Hence I am closing it.