SpiderLabs / owasp-modsecurity-crs

OWASP ModSecurity Core Rule Set (CRS) Project (Official Repository)

Home Page:https://modsecurity.org/crs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

REQUEST-941-APPLICATION-ATTACK-XSS.conf on JSON payload

jeremyjpj0916 opened this issue · comments

Description

So I have an admin API endpoint that accepts json, it has a structure of:

{
  "config": {
      ....
      "secret_is_base64": false,
      ....
   }
}

Audit Logs / Triggered Rule Numbers

ModSecurity: Warning. Matched "Operator Rx' with parameter (?i)\s\S' against variable ARGS_NAMES:json.config.secret_is_base64' (Value: json.config.secret_is_base64' ) [file "/usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf"] [line "126"] [id "941130"] [rev ""] [msg "XSS Filter - Category 3: Attribute Vector"] [data "Matched Data: _base64 found within ARGS_NAMES:json.config.secret_is_base64: json.config.secret_is_base64"] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-xss"] [tag "OWASP_CRS"] [tag "OWASP_CRS/WEB_ATTACK/XSS"] [tag "WASCTC/WASC-8"] [tag "WASCTC/WASC-22"] [tag "OWASP_TOP_10/A3"] [tag "OWASP_AppSensor/IE1"] [tag "CAPEC-242"] [hostname "10.131.27.113"] [uri "/admin-api/routes/16909564-3bc9-4b79-a56c-800a19df14d0/plugins"] [unique_id "158172271184.639456"] [ref "o21,7o22,6v0,28t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls"]
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator Ge' with parameter 5' against variable TX: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.131.27.113"] [uri "/admin-api/routes/16909564-3bc9-4b79-a56c-800a19df14d0/plugins"] [unique_id "158172271184.639456"] [ref ""]

So this rule here got hit:

SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s\S]((?:x(?:link:href|html|mlns)|!ENTITY.*?(?:SYSTEM|PUBLIC)|data:text\/html|formaction|\@import|base64)\b|pattern\b.*?=)" \

To fix it locally we could modify it to this:

(?i)[\s\S]((?:x(?:link:href|html|mlns)|!ENTITY.*?(?:SYSTEM|PUBLIC)|data:text\/html|formaction|\@import)\b|pattern\b.*?=)

Dropping the |base64 from the check and only leaving the @import. But I imagine the base64 is there must be a reason, so is there a way to improve the rule to not care about the word base64 in a harmless http body as string situation without losing the detection of whatever threat it was attempting to mitigate?

Your Environment

  • CRS version 3.2
  • Paranoia level setting: 1
  • ModSecurity version 3.0.4
  • Web Server and version nginx
  • Operating System and version: Alpine Linux

You should play with ctl:ruleRemoveTargetById in your REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf - just append to the end of your copy:

SecRule REQUEST_URI "@beginsWith /your_api_endpoint" \
    "id:10001,\
    phase:1,\
    t:none,\
    pass,\
    nolog,\
    ctl:ruleRemoveTargetById=949110;ARGS_NAMES:json.config.secret_is_base64"

Of course, you have to replace the URI by the correct pattern. There are lot of examples (in the file above) to solve similar problems like this. Don't forget to check the id of rule, it must be unique.

Ah so that is how yall get around lots of edge cases with CRS, whitelist on URI in many cases and take what the attack vector prints out and drop it in an excludes logic override. Seems elegant enough, otherwise I imagine its impossible to please everyone with a ruleset without the regex's and checks becoming not maintainable.

Thanks!