mod-security

ModSecurity / CRS: Need help writing a custom rule to whitelist false-positives - Rule 951220/951120 (user listing an SQL programming book for sale)


ModSecurity 3.0.8 ModSecurity-Nginx 1.0.3 CRS: 4.0.0-rc1

I have a marketplace where users list various things for sale. One such item is a used Microsoft SQL book. ModSecurity is complaining about this:

---CBSB85oo---A--
[10/Nov/2022:01:04:59 +0000] 166804229999.091612 66.249.70.172 53858 ***.***.***.*** 443
---CBSB85oo---B--
GET /sale/microsoft-sql-server-2008-r2-standard-w-5-cals-1-install-download-delivery-1634636/ HTTP/1.1
Host: www.*********.com
AMP-Cache-Transform: google;v="1..8"
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/signed-exchange;v=b3,application/xml;q=0.9,*/*;q=0.8
From: googlebot(at)googlebot.com
User-Agent: Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.5304.87 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Accept-Encoding: gzip, deflate, br

---CBSB85oo---F--
HTTP/1.1 403
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Cache-Control: no-store, no-cache, must-revalidate
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
Set-Cookie: NEWSESSID=n2b1ct0ipgh8qj5ti8ia0en134; path=/; HttpOnly
Pragma: no-cache
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Date: Thu, 10 Nov 2022 01:04:59 GMT
Server: nginx
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin
Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()

---CBSB85oo---H--
ModSecurity: Warning. Matched "Operator `Rx' with parameter `(?i)(?:System\.Data\.OleDb\.OleDbException|\[Microsoft\]\[ODBC SQL Server Driver\]|\[Macromedia\]\[SQLServer JDBC Driver\]|\[SqlException|System\.Data\.SqlClient\.SqlException|Unclosed quotation mark  (641 characters omitted)' against variable `RESPONSE_BODY' (Value: `<!DOCTYPE html>\x0d\x0a<html lang="en" prefix="og: http://ogp.me/ns#">\x0d\x0a<head>\x0d\x0a  <meta  (74840 characters omitted)' ) [file "/etc/nginx/modsec/coreruleset-4.0.0-rc1/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf"] [line "312"] [id "951220"] [rev ""] [msg "mssql SQL Information Leakage"] [data "Matched Data: SQL Server 2008 R2 Standard w/5 cals -1 Install (Download Delivery) For Sale</title>\x0d\x0a  <meta name="Description" content="For Sale: Microsoft SQL Server 2008 R2 Standard w/5 cals -1 Inst (64617 characters omitted)"] [severity "2"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-mssql"] [tag "attack-disclosure"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/118/116/54"] [hostname "***.***.***.***"] [uri "/sale/microsoft-sql-server-2008-r2-standard-w-5-cals-1-install-download-delivery-1634636/"] [unique_id "166804229999.091612"] [ref "o179,64776v572,65688"]
ModSecurity: Access denied with code 403 (phase 4). Matched "Operator `Ge' with parameter `4' against variable `TX:BLOCKING_OUTBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/etc/nginx/modsec/coreruleset-4.0.0-rc1/rules/RESPONSE-959-BLOCKING-EVALUATION.conf"] [line "186"] [id "959100"] [rev ""] [msg "Outbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "***.***.***.***"] [uri "/sale/microsoft-sql-server-2008-r2-standard-w-5-cals-1-install-download-delivery-1634636/"] [unique_id "166804229999.091612"] [ref ""]

I'm fairly inexperienced with writing custom CRS exclusion rules, but I'm sure someone has had to deal with this same issue, where various programming books are listing for sale and ModSecurity gets thrown off by it with rule 921220.

In addition, there were a few other listings, such as the following that trigger a similar rule 921120:

---4N6WNSFo---A--
[09/Nov/2022:02:08:59 +0000] 166795973938.894013 159.148.57.6 25181 ***.***.***.*** 443
---4N6WNSFo---B--
GET /sale/yamaha-g100iiib100iiien-operating-guide-by-download-mauritron-203723-200170/ HTTP/1.1
Host: www.**********e.com
User-Agent: Mozilla/5.0 (compatible; GeedoBot; +http://www.geedo.com/bot.html)
Accept: text/html, application/xhtml+xml, application/xml; q=0.9, */*; q=0.8
Accept-Encoding: gzip

---4N6WNSFo---F--
HTTP/1.1 403
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Cache-Control: no-store, no-cache, must-revalidate
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Vary: Accept-Encoding
X-XSS-Protection: 1; mode=block
Set-Cookie: NEWSESSID=07h58j65hep9tfduebjbn25qg5; path=/; HttpOnly
Pragma: no-cache
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Date: Wed, 09 Nov 2022 02:08:59 GMT
Server: nginx
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin
Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()

---4N6WNSFo---H--
ModSecurity: Warning. Matched "Operator `Rx' with parameter `(?i:ORA-[0-9][0-9][0-9][0-9]|java\.sql\.SQLException|Oracle error|Oracle.*Driver|Warning.*oci_.*|Warning.*ora_.*)' against variable `RESPONSE_BODY' (Value: `<!DOCTYPE html>\x0d\x0a<html lang="en" prefix="og: http://ogp.me/ns#">\x0d\x0a<head>\x0d\x0a  <meta  (68173 characters omitted)' ) [file "/etc/nginx/modsec/coreruleset-4.0.0-rc1/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf"] [line "69"] [id "951120"] [rev ""] [msg "Oracle SQL Information Leakage"] [data "Matched Data: ora-7025 found within RESPONSE_BODY"] [severity "2"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-oracle"] [tag "attack-disclosure"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/118/116/54"] [hostname "***.***.***.***"] [uri "/sale/yamaha-g100iiib100iiien-operating-guide-by-download-mauritron-203723-200170/"] [unique_id "166795973938.894013"] [ref "o37082,8v298,59690"]
ModSecurity: Access denied with code 403 (phase 4). Matched "Operator `Ge' with parameter `4' against variable `TX:BLOCKING_OUTBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/etc/nginx/modsec/coreruleset-4.0.0-rc1/rules/RESPONSE-959-BLOCKING-EVALUATION.conf"] [line "186"] [id "959100"] [rev ""] [msg "Outbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "***.***.***.***"] [uri "/sale/yamaha-g100iiib100iiien-operating-guide-by-download-mauritron-203723-200170/"] [unique_id "166795973938.894013"] [ref ""]

How should I deal with listings like this, and how should I craft the custom CRS rule to prevent users from being blocked from pages like these? Also, I do not use an Microsoft or Oracle server, but it would be nice to keep as many of the CRS rules as possible without having to turn the Engine off for whole website directories such as "/sale/" (every item listed for sale).

Thanks


Solution

  • Try this exclusion rule (for both cases):

    SecRule REQUEST_FILENAME "@beginsWith /sale/" \
        "id:1000,\
        phase:1,\
        pass,\
        t:none,\
        nolog,\
        ctl:ruleRemoveTargetById=951120;RESPONSE_BODY,\
        ctl:ruleRemoveTargetById=951220;RESPONSE_BODY"