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

Rule 930120 JSON/XML Bodies with profile in the name or nested reference?

jeremyjpj0916 opened this issue · comments

Description

Looking at some recent blocks thought I would bring up a case and see if this was "as designed" or a bug of sorts. We have plenty of API services that pass some for of the word profile as a JSON body parameter, sometimes in nested JSON too. These are blocked and I am not sure if it was intentional design or is it because of json parser doing like Object.profile.CoolField or Object.someProfile.CoolField etc.

Audit Logs / Triggered Rule Numbers

Example Payloads:

{
  "phoneNumber": "1-800-TEST-MEEE",
  "profileStartDate": "2020-02-14",
  "profileStopDate": "2020-02-24",
  "brokerId": "64450"
}
{
  "addDate": "2019-04-10T18:59:10",
  "addBy": 999999,
  "businessSegmentId": 1,
  "changeDate": "2020-02-13T22:46:31",
  "changeBy": 32,
  "logicalDelete": false,
  "profile": {
    "userRowId": 32
  }
}

Rule hit:

https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/v3.2/master/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf#L76

ModSecurity: Warning. Matched "Operator PmFromFile' with parameter lfi-os-files.data' against variable ARGS_NAMES:json.profileStopDate' (Value: json.profileStopDate' ) [file "/usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "76"] [id "930120"] [rev ""] [msg "OS File Access Attempt"] [data "Matched Data: .profile found within ARGS_NAMES:json.profileStopDate: json.profilestopdate"] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "OWASP_CRS"] [tag "OWASP_CRS/WEB_ATTACK/FILE_INJECTION"] [tag "WASCTC/WASC-33"] [tag "OWASP_TOP_10/A4"] [tag "PCI/6.5.4"]

ModSecurity: Warning. Matched "Operator PmFromFile' with parameter lfi-os-files.data' against variable ARGS_NAMES:json.profile.userRowId' (Value: json.profile.userRowId' ) [file "/usr/local/owasp-modsecurity-crs-3.2.0/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "76"] [id "930120"] [rev ""] [msg "OS File Access Attempt"] [data "Matched Data: .profile found within ARGS_NAMES:json.profile.userRowId: json.profile.userrowid"] [severity "2"] [ver "OWASP_CRS/3.2.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "OWASP_CRS"] [tag "OWASP_CRS/WEB_ATTACK/FILE_INJECTION"] [tag "WASCTC/WASC-33"] [tag "OWASP_TOP_10/A4"] [tag "PCI/6.5.4"]

Of all words in that referenced file lfi-os-files.data the .profile is the only one I think that probably would cause many frequent false positives with API calls, the word profile is a common one. But was the intent that that file be parsed like that so the regex evaluation would look for *profile or was the original intent to try to find within the JSON body a string literal ".profile" ?

https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/v3.2/master/rules/lfi-os-files.data

Currently we dropped .profile from the lfi-os-files.data file but maybe there is a more secure/appropriate alternative here or this is a bug where the rule was meant to look for .profile and not just words containing leading chars + profile or json object mapping causing a string literal evaluation of the json object to have .profile in the path reference(ex: json.profile.newCoolField).

Your Environment

  • CRS version (e.g., v3.2.0): 3.2 master
  • Paranoia level setting: 1
  • ModSecurity version (e.g., 2.9.3): 3.0.4
  • Web Server and version (e.g., apache 2.4.41): nginx
  • Operating System and version: Alpine linux

Confirmation

[x] I have removed any personal data (email addresses, IP addresses,
passwords, domain names) from any logs posted.

From slack:

Hi @jeremy Justus, this is a know issue. See this:
owasp-modsecurity/ModSecurity#2136
we discussed about here:
#1496
ModSecurity (both v2 and v3) stores the JSON tree in a "flat" hierarcy. The keys and values loaded into a "dictionary-like" structure, keys will be converted into "json.key1.key2.blaa..." if the payload looks like {"key1": {"key2":...}}. Therefore if your payload contains the {"profile":...} then the new structure will stored as json.profile, and the LFI pattern .profile fill match with operator @pmFromFile. You can replace the .profile by the ^.profile or something similar. Or change the keys in the payload.
That's it. 🙂
#2136 MS3 false positive: incorrect match of HTTP POST body with string in`lfi-os-files.data'
https://github.com/SpiderLabs/ModSecurity|SpiderLabs/ModSecuritySpiderLabs/ModSecurity | Jul 24th, 2019 | Added by GitHub
#1496 Monthly Chat Agenda August (2019-08-05)
https://github.com/SpiderLabs/owasp-modsecurity-crs|SpiderLabs/owasp-modsecurity-crsSpiderLabs/owasp-modsecurity-crs | Aug 2nd, 2019 | Added by GitHub

As such closing this issue for now. Likely needs a better resolution long term by ModSec + CRS working together.