Giter Club home page Giter Club logo

nextcloud-rule-exclusions-plugin's Introduction

OWASP CRS - Nextcloud Rule Exclusions Plugin

Integration tests

Description

This plugin contains rule exclusions for Nextcloud, a productivity platform and file hosting service. These rule exclusions are designed to resolve common false positives and allow for easier integration with the OWASP CRS (CRS).

Supported apps

Due to how feature rich Nextcloud is, not all apps in Nextcloud can be supported (Especially 3rd party apps). False positives that are due to unsupported apps within Nextcloud must be resolved by a custom rule exclusion.

Additional apps may be supported if there is enough demand from the community, but in general, support for apps made by 3rd parties (not Nextcloud) won't be added.

App Name Status
Nextcloud Files Supported ✅
Nextcloud Photos Supported ✅
Nextcloud Calendar Supported ✅
Nextcloud Contacts Supported ✅
Nextcloud Teams (Formerly Circles) Supported ✅
Nextcloud Mail Supported ✅
Nextcloud Deck Supported ✅
Nextcloud Office Supported ✅
Nextcloud Notes Supported ✅
Nextcloud Text Editor Supported ✅
Nextcloud Recognize Supported ✅
Nextcloud Cookbook Supported ✅
Nextcloud Talk Not supported ❌
Nextcloud Forms Not supported ❌
Nextcloud Polls Not supported ❌
Nextcloud Unspash Not supported ❌
Nextcloud Collectives Not supported ❌
Nextcloud News Not supported ❌
Nextcloud Maps Not supported ❌
Cospend Not supported ❌
Breeze Dark Not supported ❌
OnlyOffice Not supported ❌
Nextcloud Tables Not supported ❌
Nextcloud Assistant Not supported ❌
ownCloud Music Not supported ❌

Installation

For full and up to date instructions for the different available plugin installation methods, refer to How to Install a Plugin in the official CRS documentation.

Increasing max upload size

Large uploads can be modified with SecRequestBodyLimit. Or they can be more controlled by using the following:

SecRule REQUEST_FILENAME "@endsWith /index.php/apps/files/ajax/upload.php" \
    "id:9508610,\
    phase:1,\
    t:none,\
    nolog,\
    ctl:requestBodyLimit=1073741824"

ctl:requestBodyLimit is not supported in libmodsecurity3, Nginx users can increase max upload size by using the following:

location /index.php/apps/files/ajax/upload.php { modsecurity_rules 'SecRequestBodyLimit 1073741824'; }

Apache libmodsecurity3 Example:

 <location "/index.php/apps/files/ajax/upload.php">
    modsecurity_rules 'SecRequestBodyLimit 1073741824'
</location>

Relaxing file upload restrictions

To relax upload restrictions for only the php files that need it, you put something like this in crs-setup.conf:

SecRule REQUEST_FILENAME "@rx /(?:remote\.php|index\.php)/" \
    "id:9508600,\
    phase:2,\
    t:none,\
    nolog,\
    pass,\
    setvar:'tx.restricted_extensions=.bak/ .config/ .conf/'"

Increasing max request body size

The Nextcloud desktop client occasionally sends large request bodies not containing any uploaded files. ModSecurity will block request bodies larger than 131KB, adjusting SecRequestBodyNoFilesLimit to 141KB works for all scenarios tested.

Nginx libmodsecurity3 Example:

location /remote.php/dav/files/ { modsecurity_rules 'SecRequestBodyNoFilesLimit 144384'; }

Apache modsecurity2 Example:

<location "/remote.php/dav/files/">
   SecRequestBodyNoFilesLimit 144384
</location>

Apache libmodsecurity3 Example:

<location "/remote.php/dav/files/">
   modsecurity_rules 'SecRequestBodyNoFilesLimit 144384'
</location>

Testing

After the plugin is enabled, Nextcloud should work without problems caused by CRS (for example, false positives while blocking requests). If problems still occur then please file a new issue on GitHub. (Note that high paranoia level deployments may require additional tuning beyond this plugin.)

License

Copyright (c) 2022-2024 OWASP CRS project. All rights reserved.

The OWASP CRS and its official plugins are distributed under Apache Software License (ASL) version 2. Please see the enclosed LICENSE file for full details.

nextcloud-rule-exclusions-plugin's People

Contributors

airween avatar azurit avatar dune73 avatar esadcetiner avatar mhastu avatar mivek avatar redxanadu avatar tgion avatar theseion avatar xhoenix avatar yeapguy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nextcloud-rule-exclusions-plugin's Issues

FP playing video file

Hello:
Trying to play a video file does not work, produces FP with the following log:
Thanks,

---gE5zegJB---A--
[30/May/2024:20:20:14 +1000] 12.345 192.168.1.1 1 192.168.1.1 443
---gE5zegJB---B--
PROPFIND /public.php/webdav/movie.mkv HTTP/2.0
x-requested-with: XMLHttpRequest
authorization: Basic OUt6WkNhd2VyeGlRRWdLOg==
content-type: text/plain;charset=UTF-8
user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.952 YaBrowser/24.4.1.952 (beta) Yowser/2.5 Safari/537.36
sec-fetch-site: same-origin
depth: 0
sec-ch-ua-mobile: ?0
origin: https://origin
requesttoken: requesttoken
sec-ch-ua-platform: "Linux"
accept: text/plain,application/xml
sec-ch-ua: "Chromium";v="122", "Not(A:Brand";v="24", "YaBrowser";v="24"
content-length: 539
host: host
sec-fetch-mode: cors
sec-fetch-dest: empty
accept-encoding: gzip, deflate, br
cookie: cookie
accept-language: en;q=0.9,es;q=0.8

---gE5zegJB---D--

---gE5zegJB---E--
<html>\x0d\x0a<head><title>403 Forbidden</title></head>\x0d\x0a<body>\x0d\x0a<center><h1>403 Forbidden</h1></center>\x0d\x0a<hr><center>nginx</center>\x0d\x0a</body>\x0d\x0a</html>\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a<!-- a padding to disable MSIE and Chrome friendly error page -->\x0d\x0a

---gE5zegJB---F--
HTTP/2.0 403
X-Frame-Options: SAMEORIGIN
X-Robots-Tag: noindex, nofollow
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Permitted-Cross-Domain-Policies: none
Connection: close
X-Content-Type-Options: nosniff
Content-Type: text/html
X-Download-Options: noopen
Content-Length: 548
Date: Thu, 30 May 2024 10:20:14 GMT
Server: nginx
X-XSS-Protection: 1; mode=block

---gE5zegJB---H--
ModSecurity: Warning. Matched "Operator `Within' with parameter `|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudev (16 characters omitted)' against variable `TX:content_type' (Value: `|text/plain|' ) [file "/usr/lib/nginx/coreruleset/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "993"] [id "920420"] [rev ""] [msg "Request content type is not allowed by policy"] [data "|text/plain|"] [severity "2"] [ver "OWASP_CRS/4.0.0"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153"] [tag "PCI/12.1"] [hostname "host"] [uri "/public.php/webdav/movie.mkv"] [unique_id "12.345"] [ref "o0,10v552,24t:lowercase"]
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/usr/lib/nginx/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "176"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.0.0"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "host"] [uri "/public.php/webdav/movie.mkv"] [unique_id "12.345"] [ref ""]

---gE5zegJB---I--

---gE5zegJB---J--

---gE5zegJB---Z--

False positives

Hi there, lots of 921110 errors...

ModSecurity: Warning. Matched "Operator `Rx' with parameter `(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\s+(?:\/|\w)[^\s]*(?:\s+http\/\d|[\r\n])' against variable `REQUEST_BODY' (Value: `<?xml version="1.0" ?>\x0a<d:propfind xmlns:d="DAV:">\x0a <d:prop>\x0a <d:getetag/>\x0a </d:pro (23 characters omitted)' ) [file "/etc/modsecurity/owasp/coreruleset/rules/REQUEST-921-PROTOCOL-ATTACK.conf"] [line "33"] [id "921110"] [rev ""] [msg "HTTP Request Smuggling Attack"] [data "Matched Data: propfind xmlns:d="dav:">\x0a found within REQUEST_BODY: <?xml version="1.0" ?>\x0a<d:propfind xmlns:d="dav:">\x0a <d:prop>\x0a <d:getetag/>\x0a </d:prop>\x0a</d:propfind>\x0a"] [severity "2"] [ver "OWASP_CRS/3.3.2"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272/220/33"] [hostname "xxxxxxxxx"] [uri "/remote.php/dav/files/a.xxxxxxxxx/"] [unique_id "166756463217.934518"] [ref "o26,25v844,105t:urlDecodeUni,t:htmlEntityDecode,t:lowercase"]

just detecting:

---fIkF7ECV---C--
<?xml version="1.0" ?>
**<d:propfind xmlns:d="DAV:">**
  <d:prop>
    <d:getetag/>
  </d:prop>
</d:propfind>

Maybe could be good to include an exception for this.

Thanks.

FP when sharing special named folders in Android app

When creating a sharing link in a folder in the Android client named e.g. "tmp" a false positive is created.
ModSecurity: Warning. Matched phrase "/tmp/" at ARGS:path. [file "/etc/modsecurity/crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf"] [line "116"] [id "930120"] [msg "OS File Access Attempt"] [data "Matched Data: /tmp/ found within ARGS:path: /tmp/"] [severity "CRITICAL"] [ver "OWASP_CRS/4.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-lfi"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153/126"] [tag "PCI/6.5.4"] [uri "/ocs/v2.php/apps/files_sharing/api/v1/shares"]

FP when uploading from Android client

The REQUEST_BODY of uploaded files from the Android client is analyzed, which leads to false positives. I tried adding ctl:ruleRemoveTargetById=921110;REQUEST_BODY to rule 9508174, which did not fix the issue.

Relevant log:

ModSecurity: Warning. Pattern match "(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\\\\s+(?:\\\\/|\\\\w)[^\\\\s]*(?:\\\\s+http\\\\/\\\\d|[\\\\r\\\\n])" at REQUEST_BODY. [file "/etc/modsecurity/crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf"] [line "53"] [id "921110"] [msg "HTTP Request Smuggling Attack"] [data "Matched Data: [raw data] found within REQUEST_BODY: [raw data]..."] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.5"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [ [hostname "example.org"] [uri "/remote.php/dav/uploads/user/[...]"] [unique_id "[...]"]

Tip to get this plugin working

Hi,

i just installed ModSecurity (2.9.7) and OWASP_CRS (3.3.4) for my Nextcloud installation.
As expected, nothing worked anymore, which is why I tried to install this plugin by following the mentioned https://coreruleset.org/docs/concepts/plugins/#how-to-install-a-plugin
So I created the crs/plugins folder and placed the config files inside that folder:

media@media-server:~$ ls -l /etc/modsecurity/crs/plugins/
total 28
-rw-r--r-- 1 root root 22806 Mai  9 12:14 nextcloud-rule-exclusions-before.conf
-rw-r--r-- 1 root root  1634 Mai  9 12:14 nextcloud-rule-exclusions-config.conf

But I saw no difference in appearance (browser apps do not work, desktop client can't connect) and in the audit.log, as if the plugin does not load at all:

sudo tail -f /var/log/apache2/modsec_audit.log
Message: Warning. Match of "within %{tx.allowed_methods}" against "REQUEST_METHOD" required. [file "/usr/share/modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf"] [line "44"] [id "911100"] [msg "Method is not allowed by policy"] [data "PUT"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.4"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272/220/274"] [tag "PCI/12.1"]
Message: Access denied with code 403 (phase 2). Operator GE matched 5 at TX:anomaly_score. [file "/usr/share/modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "94"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.4"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"]
Message: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/usr/share/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "92"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): individual paranoia level scores: 5, 0, 0, 0"] [ver "OWASP_CRS/3.3.4"] [tag "event-correlation"]
Apache-Error: [file "apache2_util.c"] [line 275] [level 3] [client 192.168.X.X] ModSecurity: Warning. Match of "within %{tx.allowed_methods}" against "REQUEST_METHOD" required. [file "/usr/share/modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf"] [line "44"] [id "911100"] [msg "Method is not allowed by policy"] [data "PUT"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.4"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272/220/274"] [tag "PCI/12.1"] [hostname "REDACTED.ddns.net"] [uri "/ocs/v2.php/apps/user_status/api/v1/heartbeat"] [unique_id "ZFoiGy9GqzS5o9NoQUbhiAAAAAo"]
Apache-Error: [file "apache2_util.c"] [line 275] [level 3] [client 192.168.X.X] ModSecurity: Access denied with code 403 (phase 2). Operator GE matched 5 at TX:anomaly_score. [file "/usr/share/modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "94"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.4"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "REDACTED.ddns.net"] [uri "/ocs/v2.php/apps/user_status/api/v1/heartbeat"] [unique_id "ZFoiGy9GqzS5o9NoQUbhiAAAAAo"]
Apache-Error: [file "apache2_util.c"] [line 275] [level 3] [client 192.168.X.X] ModSecurity: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/usr/share/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "92"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): individual paranoia level scores: 5, 0, 0, 0"] [ver "OWASP_CRS/3.3.4"] [tag "event-correlation"] [hostname "REDACTED.ddns.net"] [uri "/index.php/error/403"] [unique_id "ZFoiGy9GqzS5o9NoQUbhiAAAAAo"]
Action: Intercepted (phase 2)
Apache-Handler: proxy:unix:/run/php/php8.1-fpm.sock|fcgi://localhost
Stopwatch: 1683628571613387 72442 (- - -)
Stopwatch2: 1683628571613387 72442; combined=5290, p1=648, p2=4462, p3=0, p4=0, p5=180, sr=138, sw=0, l=0, gc=0
Producer: ModSecurity for Apache/2.9.7 (http://www.modsecurity.org/); OWASP_CRS/3.3.4.
Server: Apache/2.4.57 (Ubuntu)
Engine-Mode: "ENABLED"

So I went digging for a bit.
Apache should load the CRS from here:

media@media-server:~$ cat /etc/apache2/mods-enabled/security2.conf
<IfModule security2_module>
        ...
	# Include OWASP ModSecurity CRS rules if installed
	IncludeOptional /usr/share/modsecurity-crs/owasp-crs.load
</IfModule>

And in the .load file it should load the config files:

media@media-server:~$ cat /usr/share/modsecurity-crs/owasp-crs.load
##
## This file loads OWASP CRS's rules when the package is installed
## It is Included by libapache2-mod-security2
##
Include /etc/modsecurity/crs/crs-setup.conf
IncludeOptional /etc/modsecurity/crs/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf
Include /usr/share/modsecurity-crs/rules/*.conf
IncludeOptional /etc/modsecurity/crs/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf

I felt like there should be a Include in that file for the plugins, so i put those in myself:
Include /etc/modsecurity/crs/plugins/-config.conf
Include /etc/modsecurity/crs/plugins/
-before.conf

And now it works.
That took me a bit of time so I thought I would share this here, it would be nice if this information could be put into https://github.com/coreruleset/nextcloud-rule-exclusions-plugin#installation so others can save some time and hassle :)

Erroneously launching XML parser

Hi,
rule 9508112 switches on XML parser for all calls to /remote\.php/dav/systemtags(?:-relations)?, like so:

# File manager: system tags
# Allow the data type 'text/plain'
# Since the content is actually XML, we switch on the XML parser
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/systemtags(?:-relations)?/" \
    "id:9508112,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'nextcloud-rule-exclusions-plugin/1.0.0',\
    ctl:requestBodyProcessor=XML,\
    setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type} |text/plain|'"

However, this should only be done if the content-type is actually text/plain. Nextcloud also calls this path with content-type application/json (when creating and assigning tags), in which case the XML parser obviously fails. This then results in an internal server error.

I fixed this issue on my machine using an additional *-after.conf plugin file with a chained rule, where the XML parser is only loaded for text/plain:

# fix XML parsing error where nextcloud actually uses JSON

SecRuleRemoveById 9508112

# File manager: system tags
# Allow the data type 'text/plain'
# if content-type is 'text/plain', the content is actually XML. so we switch on the XML parser
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/systemtags(?:-relations)?/" \
    "id:999999998,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'nextcloud-rule-exclusions-plugin/1.0.0',\
    setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type} |text/plain|'"
    SecRule REQUEST_HEADERS:Content-Type "text/plain" \
        "id:999999999,\
         phase:1,\
         t:none,\
         nolog,\
         ctl:requestBodyProcessor=XML"

I don't know if this is a good solution or if it breaks other rules, so any comment would be appreciated.

Nextcloud 25 False Positives

Hello CRS Team makers!

I tried to setup a calendar+contact+webauthn only 25.0.1 Nextcloud server with ModSecurity paranoia level 2 and encountered some false positive that i would like to share with you.

  • Pretty URLs.
    I guess every SecRule REQUEST_FILENAME "@contains /index.php/$CONTROLLER should be rewritten SecRule REQUEST_FILENAME "@contains /$CONTROLLER" especially cause it concerns passwords endpoint ⭕ /login and /settings

  • Address-book and calendar deletion&restoration are done through DELETE and MOVE methods:
    From:

# Allow modifying contacts via the web interface
SecRule REQUEST_METHOD "@streq PUT" \
    "id:9003321,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    chain"
    SecRule REQUEST_FILENAME "@contains /remote.php/dav/addressbooks/" \
        "t:none,\
        ctl:ruleRemoveById=200002"

to:

SecRule REQUEST_METHOD "@rx (PUT|DELETE|MOVE)" \
    "id:9003321,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    chain"
    SecRule REQUEST_FILENAME "@contains /remote.php/dav/addressbooks/" \
        "t:none,\
        ctl:ruleRemoveById=200002"

Same thing with the /remote.php/dav/calendars/URI.

  • App theming requires a PUT method to do it's job:
SecRule REQUEST_FILENAME "@rx /ocs/v[0-9]+\.php/apps/theming" \
    "id:XXXXX,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    setvar:'tx.allowed_methods=%{tx.allowed_methods} PUT'"
  • Calendar appointment feature requires DELETE and PUT methods to delete and edit:
SecRule REQUEST_FILENAME "@contains /apps/calendar/v1/appointment_configs/" \
    "id:XXXXX,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    setvar:'tx.allowed_methods=%{tx.allowed_methods} DELETE PUT'"
  • Recently contacted contact picture returns 501 instead of 404 ( 🤷 )
SecRule RESPONSE_STATUS "@streq 501" \
    "id:XXXXX,\
    phase:4,\
    pass,\
    t:none,\
    nolog,\
    chain" \
    SecRule REQUEST_FILENAME "@contains z-app-generated--contactsinteraction--recent" \
        "t:none,\
        ctl:ruleRemoveById=950100"

When search field is looking into the recent contact list, it will trigger an SQL injection error due to...the uri name (see above):
The following rule should be covered by the Nextcloud exclude rule id:9003125 but URI and ARGS changed between NC20 and NC25.

SecRule REQUEST_FILENAME "@contains /ocs/v[0-9]+\.php/search/providers" \
    "id:XXXXX,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    ctl:ruleRemoveTargetById=920230;ARGS:from,\
    ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:from,\
    ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:term"
  • Webauthn Plugin triggers up to 5 attack-sqli rules while registering, adding and removing a physical token over 3 URLs (/settings/api/personal/webauthn/registration, /apps/twofactor_webauthn/settings/finishregister and /login/challenge/webauthn).
    I overdone it but this way i know i won't break my auth.
SecRule REQUEST_FILENAME "@contains webauthn" \
    "id:XXXXX,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:json.data,\
    ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:challenge"

Same topic, removing a webauthn key requires the DELETE Method:

SecRule REQUEST_FILENAME "@contains /settings/api/personal/webauthn" \
    "id:XXXXX,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    setvar:'tx.allowed_methods=%{tx.allowed_methods} DELETE'"
  • Removing an app password requires DELETE method on /settings/personal/authtokens URI:
SecRule REQUEST_FILENAME "@contains /settings/personal/authtokens" \
    "id:XXXXX,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    setvar:'tx.allowed_methods=%{tx.allowed_methods} DELETE'"
  • Nextcloud is full of multiple input fields like appointment name and description or Webauthn security key name which are sensible to attack-sqli, i don't know if it must be excluded.
SecRule REQUEST_FILENAME "@contains /apps/calendar/v1/appointment_configs/" \
    "id:XXXXX,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    ctl:ruleRemoveTargetByID=932200;ARGS:json.description,\
    ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:json.description,\

I am kinda noob regarding ModSecurity and OWASP, please let me know if i did it wrong or if you need more data.

Regards!

Cookie values collision with 932250 and 932236

I've just hit this... Nextcloud gave this client a cookie with value lsnsd0d3arsrpnrs35m3orl4rc ... eg. starting with ls... got denied, of course.

CRS: 4.0.0
Paranoia level: 2

How to reproduce the misbehavior (-> curl call)

---DbGGH79Z---B--
GET / HTTP/2.0

### Logs

---DbGGH79Z---F--
HTTP/2.0 403
Server: nginx
Date: Tue, 18 Apr 2023 11:50:07 GMT
Content-Length: 548
Content-Type: text/html
Connection: close

---DbGGH79Z---H--
ModSecurity: Warning. Matched "Operator `Rx' with parameter `(?i)(?:^|=)[\s\v]*(?:t[\"'\)\[-\x5c]*(?:(?:(?:\|\||&&)[\s\v]*)?\$[!#\(\*\-0-9\?-@_a-\{]*)?\x5c?i[\" '\)\[-\x5c]*(?:(?:(?:\|\||&&)[\s\v]*)?\$[!#\(\*\-0-9\?-@_a-\{]*)?\x5c?m[\"'\)\[-\x5c]*(?:(?:(?:\|\||& (3145 characters omitted)' against variable `REQUEST_COOKI ES:ocqx5m6nx2xn' (Value: `lsnsd0d3arsrpnrs35m3orl4rc' ) [file "/etc/nginx/modsec/conf.d/../owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "435"] [id "932250"] [rev ""] [msg "Remote Command Execution: Direct Unix Command Execution"] [data "Matched Data: ls found within REQUEST_COOKIES:ocqx5m 6nx2xn: lsnsd0d3arsrpnrs35m3orl4rc"] [severity "2"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/88"] [tag "PCI/6.5.2"] [hostname "xxx"] [uri "/"] [unique_id "168181860725.403479"] [ref "o0,2v1899,26"]

ModSecurity: Warning. Matched "Operator `Rx' with parameter `(?i)(?:(?:^|=)[\s\v]*(?:t[\"'\)\[-\x5c]*(?:(?:(?:\|\||&&)[\s\v]*)?\$[!#\(\*\-0-9\?-@_a-\{]*)?\x5c?i[\"'\)\[-\x5c]*(?:(?:(?:\|\||&&)[\s\v]*)?\$[!#\(\*\-0-9\?-@_a-\{]*)?\x5c?m[\"'\)\[-\x5c]*(?:(?:(?:\|\ (5254 characters omitted)' against variable `REQUEST_COOKIES:ocqx5m6nx2xn' (Value: `lsnsd0d3arsrpnrs35m3orl4rc' ) [file "/etc/nginx/modsec/conf.d/../owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf"] [line "1213"] [id "932236"] [rev ""] [msg "Remote Command Execution: Unix Command Injection (command without evasion)"] [data "Matched Data: ls found within REQUEST_COOKIES:ocqx5m6nx2xn: lsnsd0d3arsrpnrs35m3orl4rc"] [severity "2"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-shell"] [tag "platform-unix"] [tag "attack-rce"] [tag "paranoia-level/2"] [tag "OWASP_CRS"] [tag "capec/1000/152/248/88"] [tag "PCI/6.5.2"] [hostname "80.79.27.134"] [uri "/"] [unique_id "168181860725.403479"] [ref "o0,2v1899,26"]

ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `10' ) [file "/etc/nginx/modsec/conf.d/../owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "176"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 10)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "xxx"] [uri "/"] [unique_id "168181860725.403479"] [ref ""]

Your Environment

CRS: 4.0.0-rc1
Paranoia level: 2
Nginx: 1.20.1
OS: Rocky 9

Confirmation

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

Nextcloud Deck: reordering a list on a board hits rule 911100: Method is not allowed by policy

Description

When I try to reorder a list on a board with multiple lists, by dragging a list from one side of the board to the other, I hit this rule, 911100, I think because of the PUT:

{
  "transaction": {
    "client_ip": "xxx.xxx.xxx.xxx",
    "time_stamp": "Sat Jul 13 09:45:30 2024",
    "server_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "client_port": 29992,
    "host_ip": "xx.xx.x.xxx",
    "host_port": 443,
    "unique_id": "xxxxxxxxxxxxxxxxxxx",
    "request": {
      "method": "PUT",
      "http_version": 2.0,
      "uri": "/apps/deck/stacks/78/reorder",
      "body": "{\"order\":0}",
      "headers": {
        "origin": "https://nextcloud.example.com",
        "dnt": "1",
        "requesttoken": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "x-requested-with": "XMLHttpRequest, XMLHttpRequest",
        "content-type": "application/json",
        "accept-encoding": "gzip, deflate, br, zstd",
        "cookie": "__Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; oc_sessionPassphrase=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; xxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; xxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "content-length": "11",
        "accept-language": "en-US,en;q=0.5",
        "te": "trailers",
        "accept": "application/json, text/plain, */*",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:127.0) Gecko/20100101 Firefox/127.0",
        "sec-fetch-site": "same-origin",
        "host": "nextcloud.example.com",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors"
      }
    },
    "response": {
      "http_code": 403,
      "headers": {
        "Server": "",
        "Date": "Sat, 13 Jul 2024 07:45:30 GMT",
        "Content-Length": "146",
        "Content-Type": "text/html",
        "Connection": "close",
        "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
      }
    },
    "producer": {
      "modsecurity": "ModSecurity v3.0.12 (Linux)",
      "connector": "ModSecurity-nginx v1.0.3",
      "secrules_engine": "Enabled",
      "components": [
        "OWASP_CRS/4.4.0\""
      ]
    },
    "messages": [
      {
        "message": "Method is not allowed by policy",
        "details": {
          "match": "Matched \"Operator `Within' with parameter `GET HEAD POST OPTIONS' against variable `REQUEST_METHOD' (Value: `PUT')",
          "reference": "v0,3",
          "ruleId": "911100",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf",
          "lineNumber": "28",
          "data": "PUT",
          "severity": "2",
          "ver": "OWASP_CRS/4.4.0",
          "rev": "",
          "tags": [
            "application-multi",
            "language-multi",
            "platform-multi",
            "attack-generic",
            "paranoia-level/1",
            "OWASP_CRS",
            "capec/1000/210/272/220/274",
            "PCI/12.1"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      },
      {
        "message": "Inbound Anomaly Score Exceeded (Total Score: 5)",
        "details": {
          "match": "Matched \"Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' )",
          "reference": "",
          "ruleId": "949110",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf",
          "lineNumber": "222",
          "data": "",
          "severity": "0",
          "ver": "OWASP_CRS/4.4.0",
          "rev": "",
          "tags": [
            "anomaly-evaluation",
            "OWASP_CRS"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      }
    ]
  }
}

Maybe solution

I think fixing it might look something like this, but I'm not great at modsecurity rule exclusion stuff:

    # allow reorder deck lists
    SecRule REQUEST_URI "@rx ^/apps/deck/stacks/[0-9]+/reorder$" \
        "id:9000000,\
        phase:1,\
        pass,\
        t:none,\
        nolog,\
        setvar:'tx.allowed_methods=GET HEAD POST PUT'"

Env

CRS version: 4.4.0
ModSecurity version: ModSecurity v3.0.12 (Linux)
type of web server: ingress-nginx controller via k8s

Thanks for any help you can provide!

FP nextcloud office (collabora online)

Hello:
Saving a nc office document using the web interface of collabora online has error 'cannot save due to invalid or out-of-date token'.

nginx log:
2024/02/14 18:03:41 [error] 81112#81112: *1375 [client myip] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/usr/lib/nginx/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "176"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.0.0-rc2"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "myip"] [uri "//index.php/apps/richdocuments/wopi/files/15631_ocw9mgv9cv3x/contents"] [unique_id "170somenumber"] [ref ""], client: myip, server: myserver, request: "POST //index.php/apps/richdocuments/wopi/files/numbers_characters/contents?access_token=accesstoken&access_token_ttl=0&permission=edit HTTP/1.1", host: "myserver"

Thanks

Rule 911100 triggered as a false positive when using ios app and dismissing a notification

Hi friends!

This one might be a little more difficult to reproduce unless you own an iPad or iPhone, but I have the Nextcloud app installed on my iPad for uploading my drawings from procreate. Recently, when I tried to delete a file it was trying to upload, it showed an error that I didn't have network access and when I dismissed the error, I got the following in the logs:

{
  "transaction": {
    "client_ip": "192.168.1.1",
    "time_stamp": "Sun Jul 21 08:55:02 2024",
    "server_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "client_port": 17408,
    "host_ip": "xx.xx.xx.xx",
    "host_port": 443,
    "unique_id": "xxxxxxxxxxxx.xxxxxxxx",
    "request": {
      "method": "DELETE",
      "http_version": 2.0,
      "uri": "/ocs/v2.php/apps/notifications/api/v2/push",
      "body": "",
      "headers": {
        "host": "cloud.example.com",
        "authorization": "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "accept": "application/json",
        "content-type": "application/x-www-form-urlencoded",
        "ocs-apirequest": "true",
        "accept-language": "en-NL;q=1.0, nl-NL;q=0.9",
        "content-length": "0",
        "accept-encoding": "br;q=1.0, gzip;q=0.9, deflate;q=0.8",
        "user-agent": "Mozilla/5.0 (iOS) Nextcloud-iOS/5.4.1",
        "cookie": "__Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; oc_sessionPassphrase=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ocrkhwrly2jb=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      }
    },
    "response": {
      "http_code": 403,
      "headers": {
        "Server": "",
        "Date": "Sun,21 Jul 2024 06:55:02 GMT",
        "Content-Length": "146",
        "Content-Type": "text/html",
        "Connection": "close",
        "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
      }
    },
    "producer": {
      "modsecurity": "ModSecurity v3.0.12 (Linux)",
      "connector": "ModSecurity-nginx v1.0.3",
      "secrules_engine": "Enabled",
      "components": [
        "OWASP_CRS/4.4.0\""
      ]
    },
    "messages": [
      {
        "message": "Method is not allowed by policy",
        "details": {
          "match": "Matched \"Operator `Within' with parameter `GET HEAD POST OPTIONS' against variable `REQUEST_METHOD' (Value: `DELETE' )",
          "reference": "v0,6",
          "ruleId": "911100",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf",
          "lineNumber": "28",
          "data": "DELETE",
          "severity": "2",
          "ver": "OWASP_CRS/4.4.0",
          "rev": "",
          "tags": [
            "application-multi",
            "language-multi",
            "platform-multi",
            "attack-generic",
            "paranoia-level/1",
            "OWASP_CRS",
            "capec/1000/210/272/220/274",
            "PCI/12.1"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      },
      {
        "message": "Inbound Anomaly Score Exceeded (Total Score: 5)",
        "details": {
          "match": "Matched \"Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' )",
          "reference": "",
          "ruleId": "949110",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf",
          "lineNumber": "222",
          "data": "",
          "severity": "0",
          "ver": "OWASP_CRS/4.4.0",
          "rev": "",
          "tags": [
            "anomaly-evaluation",
            "OWASP_CRS"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      }
    ]
  }
}

Luckily, I don't think this actually breaks anything this time, just kind of clogs the logs a bit. What's weird is that this should already be caught, I think? Check out this section:

#
# [ Notifications ]
#
# Nextcloud uses notifictions to inform the user of important new details.
# Dismissing notifications
SecRule REQUEST_FILENAME "@rx /ocs/v[0-9]+\.php/apps/notifications/api/v[0-9]/notifications(?:/[0-9]+)?$" \
"id:9508701,\
phase:1,\
pass,\
t:none,\
nolog,\
ver:'nextcloud-rule-exclusions-plugin/1.2.0',\
setvar:'tx.allowed_methods=%{tx.allowed_methods} DELETE'"
# Sometimes a 502 error is returned when viewing/dismissing a notification
SecRule REQUEST_FILENAME "@rx /ocs/v[0-9]\.php/apps/notifications/api/v[0-9]/notifications$" \
"id:9508702,\
phase:3,\
pass,\
t:none,\
nolog,\
ver:'nextcloud-rule-exclusions-plugin/1.2.0',\
chain"
SecRule RESPONSE_STATUS "@streq 502" \
"t:none,\
ctl:ruleRemoveById=950100"

I'm unable to reproduce the same issue from my android, web, or native macOS apps. 🤷 Maybe we need something like this?

    # Dismissing notifications from ios?
    SecRule REQUEST_FILENAME "@rx /ocs/v[0-9]+\.php/apps/notifications/api/v[0-9]/notifications/push$" \
        "id:9508703,\
        phase:1,\
        pass,\
        t:none,\
        nolog,\
        ver:'nextcloud-rule-exclusions-plugin/1.2.0',\
        setvar:'tx.allowed_methods=%{tx.allowed_methods} DELETE'"

Files: Open images in shared folder

When accessing a publicly shared folder via link and trying to open an image inside, the following FP is produced:
ModSecurity: Warning. Match of "within %{tx.allowed_request_content_type}" against "TX:content_type" required. [file "/etc/modsecurity/crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1012"] [id "920420"] [msg "Request content type is not allowed by policy"] [data "|text/plain|"] [severity "CRITICAL"] [ver "OWASP_CRS/4.0.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153"] [tag "PCI/12.1"] [uri "/public.php/webdav/img.jpg"].

I was able to fix it with the following exclusion rule, without guarantee of safety:

# File manager: Public share
# Fix FP when opening photo
# Allow the data type 'text/plain'
# Since the content is actually XML, we switch on the XML parser
SecRule REQUEST_FILENAME "@beginsWith /public.php/webdav/" \
    "id:9508954,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'nextcloud-rule-exclusions-plugin/1.1.0',\
    chain"
    SecRule REQUEST_HEADERS:Content-Type "@beginsWith text/plain" \
        "t:none,\
        ctl:requestBodyProcessor=XML,\
        setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type} |text/plain|'"

Support Cospend App

When using the Android sync client for Cospend, "Moneybuster", the following FP appears upon creation of a new bill:
ModSecurity: Warning. Match of "within %{tx.allowed_methods}" against "REQUEST_METHOD" required. [file "/etc/modsecurity/crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf"] [line "44"] [id "911100"] [msg "Method is not allowed by policy"] [data "PUT"] [severity "CRITICAL"] [ver "OWASP_CRS/4.0.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272/220/274"] [tag "PCI/12.1"] [uri "/ocs/v2.php/apps/cospend/api/v1/projects/personal/bills/1374"]].

I was able to fix it using the following exclusion rule, but can guarantee no safety:

SecRule REQUEST_FILENAME "@rx /ocs/v[0-9]+\.php/apps/cospend/api/v[0-9]+/" \
    "id:9509000,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'nextcloud-rule-exclusions-plugin/1.0.0',\
    setvar:'tx.allowed_methods=%{tx.allowed_methods} PUT'"

Allow arbitrary filenames

I noticed that the regex of rule 933210 (PHP injection) is also applied on REQUEST_FILENAME. Is this intended behavior? I.e. do these kind of attacks also work by trying to sync special filenames or should we allow arbitrary filenames? Granted, using quotes in filenames is a bad idea, but if you receive a bunch of files and just want to save it in your cloud it is unexpected that suddenly the syncing fails, just because of the filename.

The relevant error.log:

[Mon Sep 25 09:47:56.108156 2023] [security2:error] [pid 132240] [client 0.0.0.0:0] [client 0.0.0.0] ModSecurity: Warning. Pattern match "(?:(?:\\\\(|\\\\[)[a-zA-Z0-9_.$\\"'\\\\[\\\\](){}/*\\\\s]+(?:\\\\)|\\\\])[0-9_.$\\"'\\\\[\\\\](){}/*\\\\s]*\\\\([a-zA-Z0-9_.$\\"'\\\\[\\\\](){}/*\\\\s].*\\\\)|\\\\([\\\\s]*string[\\\\s]*\\\\)[\\\\s]*(?:\\"|'))" at REQUEST_FILENAME. [file "/etc/modsecurity/crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf"] [line "503"] [id "933210"] [msg "PHP Injection Attack: Variable Function Call Found"] [data "Matched Data: (text)' (text) found within REQUEST_FILENAME: /remote.php/dav/files/text - 'text (text)' (text) - text.ext"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.5"] [tag "application-multi"] [tag "language-php"] [tag "platform-multi"] [tag "attack-injection-php"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/152/242"] [hostname "example.url"] [uri "/remote.php/dav/files/text - 'text (text)' (text) - text.ext"] [unique_id "id"]

Rules 921110, 921130 hit with the Nextcloud Deck app when trying to add code blocks to cards

Hi core rule set friends!

I tried to create a card in Nextcloud's Deck app with the following code block:

2024/07/02 15:21:45 [error] 1908#1908: *2728331 [client 192.168.1.1] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "81"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "2"] [ver "OWASP_CRS/3.3.5"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [hostname "10.42.0.34"] [uri "/_matrix/media/r0/upload"] [unique_id "171992650595.932620"] [ref ""], client: 192.168.1.1, server: xxxxxx.xxxxxx.xxxxxx, request: "POST /_matrix/media/r0/upload HTTP/1.1", host: "xxxxxx.xxxxxx.xxxxxx"

It was actually a card for fixing another modsecurity issue with matrix haha, but it gave me this error:

{
  "transaction": {
    "client_ip": "192.168.1.1",
    "time_stamp": "Tue Jul  2 15:30:46 2024",
    "server_id": "fade3de079ac9ce77586b1809c4a4",
    "client_port": 38057,
    "host_ip": "10.42.0.46",
    "host_port": 443,
    "unique_id": "171992704647.640017",
    "request": {
      "method": "PUT",
      "http_version": 2,
      "uri": "/apps/deck/cards/175",
      "body": "{\"id\":175,\"title\":\"fix modSecurity rule exception for matrix photo uploads\",\"description\":\"Moved matrix, grafana, and postgresql rules into their own plugins in this commit:  \\n<https://github.com/small-hack/argocd-apps/commit/3b10470ae85b81d2452106c2094814f0713b3f48>\\n\\nhad to reopen this\\n\\n```\\n2024/07/02 15:21:45 [error] 1908#1908: *2728331 [client 192.168.1.1] ModSecurity: Access denied with code 403 (phase 2). Matched \\\"Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `5' ) [file \\\"/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf\\\"] [line \\\"81\\\"] [id \\\"949110\\\"] [rev \\\"\\\"] [msg \\\"Inbound Anomaly Score Exceeded (Total Score: 5)\\\"] [data \\\"\\\"] [severity \\\"2\\\"] [ver \\\"OWASP_CRS/3.3.5\\\"] [maturity \\\"0\\\"] [accuracy \\\"0\\\"] [tag \\\"application-multi\\\"] [tag \\\"language-multi\\\"] [tag \\\"platform-multi\\\"] [tag \\\"attack-generic\\\"] [hostname \\\"10.42.0.34\\\"] [uri \\\"/_matrix/media/r0/upload\\\"] [unique_id \\\"171992650595.932620\\\"] [ref \\\"\\\"], client: 192.168.1.1, server: xxxxxx.xxxxxx.xxxxxx, request:\\\"POST /_matrix/media/r0/upload HTTP/1.1\\\", host: \\\"xxxxxx.xxxxxx.xxxxxx\\\"\\n```\",\"stackId\":43,\"type\":\"plain\",\"lastModified\":1719927039.722,\"lastEditor\":null,\"createdAt\":1719915377,\"labels\":[{\"id\":50,\"title\":\"matrix \",\"color\":\"0082c9\",\"boardId\":37,\"cardId\":175,\"lastModified\":0,\"ETag\":\"cfcd208495d565ef66e7dff9f98764da\"},{\"id\":145,\"title\":\"modsecurity\",\"color\":\"3e253a\",\"boardId\":37,\"cardId\":175,\"lastModified\":0,\"ETag\":\"cfcd208495d565ef66e7dff9f98764da\"}],\"assignedUsers\":[{\"id\":170,\"participant\":{\"primaryKey\":\"myuser\",\"uid\":\"myuser\",\"displayname\":\"my user\",\"type\":0},\"cardId\":175,\"type\":0}],\"attachments\":null,\"attachmentCount\":0,\"owner\":{\"primaryKey\":\"myuser\",\"uid\":\"myuser\",\"displayname\":\"my user\",\"type\":0},\"order\":0,\"archived\":false,\"done\":\"2024-07-02T10:41:06+00:00\",\"duedate\":null,\"deletedAt\":0,\"commentsUnread\":0,\"commentsCount\":0,\"ETag\":\"514f35643b51eb2c03b0829c3ba69a75\",\"overdue\":0}",
      "headers": {
        "origin": "https://cloud.mydomain.com",
        "dnt": "1",
        "requesttoken": "xxxxx/xxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxxxx=:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "x-requested-with": "XMLHttpRequest, XMLHttpRequest",
        "content-type": "application/json",
        "accept-encoding": "gzip, deflate, br, zstd",
        "cookie": "__Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; oc_sessionPassphrase=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; xxxxxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; VouchCookie=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "content-length": "1962",
        "accept-language": "en-US,en;q=0.5",
        "te": "trailers",
        "accept": "application/json, text/plain, */*",
        "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:127.0) Gecko/20100101 Firefox/127.0",
        "sec-fetch-site": "same-origin",
        "host": "cloud.mydomain.com",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors"
      }
    },
    "response": {
      "body": "<html>\r\n<head><title>403 Forbidden</title></head>\r\n<body>\r\n<center><h1>403 Forbidden</h1></center>\r\n<hr><center>nginx</center>\r\n</body>\r\n</html>\r\n",
      "http_code": 403,
      "headers": {
        "Server": "",
        "Date": "Tue, 02 Jul 2024 13:30:46 GMT",
        "Content-Length": "146",
        "Content-Type": "text/html",
        "Connection": "close",
        "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
      }
    },
    "producer": {
      "modsecurity": "ModSecurity v3.0.12 (Linux)",
      "connector": "ModSecurity-nginx v1.0.3",
      "secrules_engine": "Enabled",
      "components": [
        "OWASP_CRS/3.3.5\""
      ]
    },
    "messages": [
      {
        "message": "HTTP Request Smuggling Attack",
        "details": {
          "match": "Matched \"Operator `Rx' with parameter `(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\\s+(?:\\/|\\w)[^\\s]*(?:\\s+http\\/\\d|[\\r\\n])' against variable `REQUEST_BODY' (Value: `{\"id\":175,\"title\":\"fix modSecurity rule exception for matrix photo uploads\",\"description\":\"Moved mat (1862 characters omitted)' )",
          "reference": "o923,36v17,992t:urlDecodeUni,t:htmlEntityDecode,t:lowercaseo1058,36v1228,1962t:urlDecodeUni,t:htmlEntityDecode,t:lowercase",
          "ruleId": "921110",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf",
          "lineNumber": "34",
          "data": "Matched Data: post /_matrix/media/r0/upload http/1 found within REQUEST_BODY: {\"id\":175,\"title\":\"fix modsecurity rule exception for matrix photo uploads\",\"description\":\"moved matrix, grafana, and postgresql rules into their own plugins in this commit:  \\n<https://github.com/small-hack/argocd-apps/commit/3b10470ae85b81d2452106c2094814f0713b3f48>\\n\\nhad to reopen this\\n\\n```\\n2024/07/02 15:21:45 [error] 1908#1908: *2728331 [client 192.168.1.1] modsecurity: access denied with code 403 (phase 2). matched \\\"operator `ge' with parameter `5' against variable `tx:anomaly_score' (value: `5' ) [file \\\"/etc/nginx/owasp-modsecurity-crs/rules/request-949-blocking-evaluation.conf\\\"] [line \\\"81\\\"] [id \\\"949110\\\"] [rev \\\"\\\"] [msg \\\"inbound anomaly score exceeded (total score: 5)\\\"] [data \\\"\\\"] [severity \\\"2\\\"] [ver \\\"owasp_crs/3.3.5\\\"] [maturity \\\"0\\\"] [accuracy \\\"0\\\"] [tag \\\"application-multi\\\"] [tag \\\"language-multi\\\"] [tag \\\"platform-multi\\\"] [tag \\\"attack-generic\\\"] [hostname \\\"10.42.0.34\\\"] [uri \\\"/_matrix/media/r0/upload\\\"] [unique_id \\\"171992650595.932620\\\"] [ref \\\"\\\"], client: 192.168.1.1, server: xxxxxx.xxxxxx.xxxxxx, request: \\\"post /_matrix/media/r0/upload http/1.1\\\", host: \\\"xxxxxx.xxxxxx.xxxxxx\\\"\\n```\",\"stackid\":43,\"type\":\"plain\",\"lastmodified\":1719927039.722,\"lasteditor\":null,\"createdat\":1719915377,\"labels\":[{\"id\":50,\"title\":\"matrix \",\"color\":\"0082c9\",\"boardid\":37,\"cardid\":175,\"lastmodified\":0,\"etag\":\"cfcd208495d565ef66e7dff9f98764da\"},{\"id\":145,\"title\":\"modsecurity\",\"color\":\"3e253a\",\"boardid\":37,\"cardid\":175,\"lastmodified\":0,\"etag\":\"cfcd208495d565ef66e7dff9f98764da\"}],\"assignedusers\":[{\"id\":170,\"participant\":{\"primarykey\":\"myuser\",\"uid\":\"myuser\",\"displayname\":\"my user\",\"type\":0},\"cardid\":175,\"type\":0}],\"attachments\":null,\"attachmentcount\":0,\"owner\":{\"primarykey\":\"myuser\",\"uid\":\"myuser\",\"displayname\":\"my user\",\"type\":0},\"order\":0,\"archived\":false,\"done\":\"2024-07-02t10:41:06 00:00\",\"duedate\":null,\"deletedat\":0,\"commentsunread\":0,\"commentscount\":0,\"etag\":\"514f35643b51eb2c03b0829c3ba69a75\",\"overdue\":0}",
          "severity": "2",
          "ver": "OWASP_CRS/3.3.5",
          "rev": "",
          "tags": [
            "application-multi",
            "language-multi",
            "platform-multi",
            "attack-protocol",
            "paranoia-level/1",
            "OWASP_CRS",
            "capec/1000/210/272/220/33"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      },
      {
        "message": "HTTP Response Splitting Attack",
        "details": {
          "match": "Matched \"Operator `Rx' with parameter `(?:\\bhttp/\\d|<(?:html|meta)\\b)' against variable `ARGS:json.description' (Value: `Moved matrix, grafana, and postgresql rules into their own plugins in this commit:  \\x0a<https://git (913 characters omitted)' )",
          "reference": "o953,6v17,992t:urlDecodeUni,t:htmlEntityDecode,t:lowercase",
          "ruleId": "921130",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf",
          "lineNumber": "89",
          "data": "Matched Data: http/1 found within ARGS:json.description: moved matrix, grafana, and postgresql rules into their own plugins in this commit:  \n<https://github.com/small-hack/argocd-apps/commit/3b10470ae85b81d2452106c2094814f0713b3f48>\n\nhad to reopen this\n\n```\n2024/07/02 15:21:45 [error] 1908#1908: *2728331 [client 192.168.1.1] modsecurity: access denied with code 403 (phase 2). matched \"operator `ge' with parameter `5' against variable `tx:anomaly_score' (value: `5' ) [file \"/etc/nginx/owasp-modsecurity-crs/rules/request-949-blocking-evaluation.conf\"] [line \"81\"] [id \"949110\"] [rev \"\"] [msg \"inbound anomaly score exceeded (total score: 5)\"] [data \"\"] [severity \"2\"] [ver \"owasp_crs/3.3.5\"] [maturity \"0\"] [accuracy \"0\"] [tag \"application-multi\"] [tag \"language-multi\"] [tag \"platform-multi\"] [tag \"attack-generic\"] [hostname \"10.42.0.34\"] [uri \"/_matrix/media/r0/upload\"] [unique_id \"171992650595.932620\"] [ref \"\"], client: 192.168.1.1, server: xxxxxx.xxxxxx.xxxxxx, request: \"post /_matrix/media/r0/upload http/1.1\", host: \"xxxxxx.xxxxxx.xxxxxx\"\n```",
          "severity": "2",
          "ver": "OWASP_CRS/3.3.5",
          "rev": "",
          "tags": [
            "application-multi",
            "language-multi",
            "platform-multi",
            "attack-protocol",
            "paranoia-level/1",
            "OWASP_CRS",
            "capec/1000/210/272/220/34"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      },
      {
        "message": "Inbound Anomaly Score Exceeded (Total Score: 15)",
        "details": {
          "match": "Matched \"Operator `Ge' with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `15' )",
          "reference": "",
          "ruleId": "949110",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf",
          "lineNumber": "81",
          "data": "",
          "severity": "2",
          "ver": "OWASP_CRS/3.3.5",
          "rev": "",
          "tags": [
            "application-multi",
            "language-multi",
            "platform-multi",
            "attack-generic"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      }
    ]
  }
}

Looks like it hit the following rules: 921110, 921130, 949110.

would it make sense to have something like this added to the plugin?

SecRule REQUEST_URI "@beginsWith /apps/deck/cards" \
    "id:1000,\
    phase:1,\
    pass,\
    nolog,\
    ctl:ruleRemoveById=921110"
    
SecRule REQUEST_URI "@beginsWith /apps/deck/cards" \
    "id:1000,\
    phase:1,\
    pass,\
    nolog,\
    ctl:ruleRemoveById=921130"
    
SecRule REQUEST_URI "@beginsWith /apps/deck/cards" \
    "id:1000,\
    phase:1,\
    pass,\
    nolog,\
    ctl:ruleRemoveById=949110"

If so, I could try and submit a PR for this. If not, please let me know what the best course of action is 🙏

Env info

CRS version: 3.3.5
ModSecurity version: ModSecurity v3.0.12 (Linux)
type of web server: ingress-nginx controller via k8s

Variable expansion not working?

Describe the bug

I have a nextcloud instance and just switched from the "old" exclusions to the new plugin system.
During the tests I reckognized a problem:
Rule 9508130 should expand tx.allowed_methods:

setvar:'tx.allowed_methods=%{tx.allowed_methods} PUT PATCH CHECKOUT COPY DELETE LOCK MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH SEARCH UNLOCK REPORT TRACE jsonp'"`

tx.allowed_methods is the default value (GET HEAD POST OPTIONS), so I don't set it - but somehow it is not expanded here.
I receive the following block in my log:

---xbaiLTEY---A--
[29/Apr/2022:17:06:53 +0200] XXXX
---xbaiLTEY---B--
GET /index.php/avatar/xxx/384 HTTP/1.1
[...]
Host: XXX
User-Agent: Mozilla/5.0 (Android) Nextcloud-android/3.19.1
[...]


---xbaiLTEY---F--
HTTP/1.1 403
Date: Fri, 29 Apr 2022 15:06:53 GMT
Content-Length: 146
Content-Type: text/html
Connection: keep-alive

---xbaiLTEY---H--
ModSecurity: Warning. Matched "Operator `Within' with parameter ` PUT PATCH CHECKOUT COPY DELETE LOCK MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH SEARCH UNLOCK REPORT TRACE jsonp' against variable `REQUEST_METHOD' (Value: `GET' ) [file "/etc/nginx/modsec/coreruleset-dev/rules/REQUEST-911-METHOD-ENFORCEMENT.conf"] [line "28"] [id "911100"] [rev ""] [msg "Method is not allowed by policy"] [data "GET"] [severity "2"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-generic"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272/220/274"] [tag "PCI/12.1"] [hostname "XXX"] [uri "XXXX"] [unique_id "1651244813"] [ref "v0,3"]
ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/etc/nginx/modsec/coreruleset-dev/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "176"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.0.0-rc1"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "XXXX"] [uri "XXXX"] [unique_id "1651244813"] [ref ""]

So in the error all the methods, which are extended to tx.allowed_methods are listed (PUT PATCH CHECKOUT COPY DELETE LOCK MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH SEARCH UNLOCK REPORT TRACE jsonp), but not the default ones.

Steps to reproduce

Installed CRS with nextcloud plugin, access a shared folder via Android App

Expected behaviour

Rule 9508130 should not overwrite but add methods.

Actual behaviour

Rule 9508130 should add the methods correctly.

Your Environment

  • CRS version: 4.0.0-rc1
  • Paranoia level setting:1
  • ModSecurity version: 3.0.6
  • Web Server and version: nginx 1.21.6
  • Operating System and version: Arch Linux

Maybe someone can help me with this?

//Edit:
I just realized, that I have this issue also with other rules, e.g. 9508110 expands tx.allowed_request_content_type - and there I have the same issue.

Syntax error on line 208

This was working until today with Apache 2.4, libapache-modsecurity2 v2.9.5, CoreRuleSet 4.0, and the latest version of this plugin. Then, it abruptly stopped working, and the Apache2 service failed to start, instead showing the following error message:

> Apr 25 15:32:46 northern-paper-wasp apachectl[192098]: apache2: Syntax error on line 235 of /etc/apache2/apache2.conf: Syntax error on line 208 of /etc/crs4/plugins/nextcloud-rule-exclusions-config.conf: Expected </link> but saw </head>

What might have caused this?

Lots of FPs with NextCloud `autosaveContent`

This is the exclusion rule I'm currently using for my NextCloud Installation:-

SecRule REQUEST_URI "@beginsWith /apps/text/session/sync" \
    "id:1219,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'nextcloud-rule-exclusions-plugin/1.0.0',\
    ctl:ruleRemoveTargetById=931130;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932200;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942150;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942410;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942430;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942440;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942431;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942460;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=941340;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942550;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942131;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942200;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942210;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942300;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942370;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942380;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942520;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942490;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932235;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=933120;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=933161;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=941330;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942120;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932236;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932220;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932160;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932130;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932125;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932230;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932115;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=942340;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=932370;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=941160;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=941320;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=941110;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=941390;ARGS:autosaveContent,\
    ctl:ruleRemoveTargetById=941100;ARGS:autosaveContent"

Although it contains few rules from PL 2. I think this needs to be taken into consideration as adding something as simple as a html tag to a text file creates a lot of FPs.

Nextcloud: calDAV: false positive

Description

An iPhone trying to PUT to Nextcloud's calDAV service will be blocked by CRS.

Logs

[error] 97548#97548: *156197 [client xxx] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' ) [file "/usr/local/nginx/conf/conf.d/include/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "176"] [id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [data ""] [severity "0"] [ver "OWASP_CRS/4.0.0"] [maturity "0"] [accuracy "0"] [tag "anomaly-evaluation"] [hostname "xxx"] [uri "/remote.php/caldav/calendars/xxx/xxx/xxx.ics"] [unique_id "171045623486.423063"] [ref ""], client: xxx, server: xxx, request: "PUT /remote.php/caldav/calendars/xxx/xxx/xxx.ics HTTP/1.1", host: "xxx"

Your Environment

  • CRS version (e.g., v3.3.4): 4.0.0
  • Paranoia level setting (e.g. PL1) : PL1
  • ModSecurity version (e.g., 2.9.6):
  • Web Server and version or cloud provider / CDN (e.g., Apache httpd 2.4.54): Nginx-Proxy-Manager Plus latest
  • Operating System and version: Dockerized

Confirmation

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

FP when uploading files via desktop client

Uploading files from the (windows) desktop client produces false positives with the log:

ModSecurity: Warning. String match within "/accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/" at TX:header_name_if. [file "/etc/modsecurity/crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1128"] [id "920450"] [msg "HTTP header is restricted by policy (/if/)"] [data "Restricted header detected: /if/"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.5"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/12.1"] [hostname "example.org"] [uri "/remote.php/dav/uploads/user/4195284221/.file"]

I managed to fix it on my setup by removing /if form the restricted header list for requests uris of this form, with the following rule:

SecRule REQUEST_FILENAME "@rx /remote\.php/dav/uploads/[^/]+/[0-9]+/.file$" \
    "id:9999999999,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'nextcloud-rule-exclusions-plugin/1.0.0',\
    setvar:'tx.restricted_headers=/accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/'"

I think that removing /if from the current value of tx.restricted_headers might be more future-proof, but I don't know how to do that, hence I didn't open a pull-request.

Desktop client version: 3.11.0 (might be relevant, since this issue did not occur before)

False Positives when Uploading Large File from Linux Client

Hi, these false positives are preventing Nextcloud's Linux client from syncing an 150MB ZIP file:

[Tue Feb 14 12:56:44.692790 2023] [:error] [pid 63003] [client 127.0.0.1:46696] [client 127.0.0.1] ModSecurity: Warning. Operator EQ matched 0 at REQUEST_HEADERS. [file "/usr/share/modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "702"] [id "920340"] [msg "Request Containing Content, but Missing Content-Type header"] [severity "NOTICE"] [ver "OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [hostname "www.um-li.xyz"] [uri "/nextcloud/apps/files/"] [unique_id ...]

[Tue Feb 14 13:03:33.049500 2023] [:error] [pid 63058] [client 127.0.0.1:56006] [client 127.0.0.1] ModSecurity: Warning. Pattern match "(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\\\\s+(?:\\\\/|\\\\w)[^\\\\s]*(?:\\\\s+http\\\\/\\\\d|[\\\\r\\\\n])" at REQUEST_BODY. [file "/usr/share/modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf"] [line "52"] [id "921110"] [msg "HTTP Request Smuggling Attack"] [data "Matched Data: track 001]trck\\x00\\x00\\x00\\x04\\x00\\x00\\x00001\\x00\\xff\\xfb\\xd0\\x00i\\x06\\x00\\x0d found within REQUEST_BODY: \\x14\\xc6\\x13\\x06$\\x8c\\xc6~5\\x03\\xf9\\xa6\\xbfg\\x13p\\xa5\\x11\\xd2.\\x0e9n\\x5c\\xd7\\x8d;m\\x14\\xfc\\xaew4\\xeb\\x8bf/\\x89ou\\x1d\\xbd\\xc6\\xa1\\xe35\\xa1i\\x1esg\\x7fzq\\xdcu\\x0c\\xeef^\\xe0ma\\xae\\xc7.\\xbe\\xb1\\x5c\\x8d\\x0f\\xc8l\\xe6\\x9a\\x93\\xc5e<\\x0a\\xb6\\xce\\xd5\\xcbt\\x0ew\\xfe\\xf5)\\xdc\\x1e\\x09\\x0f~q\\xbcs\\x0c\\x9d\\xd6\\xe9\\x8f:\\x8f\\x93\\xb8y\\xd1f\\xb8ii\\x18\\x9d\\xa8\\xdbn\\xd6%,\\xd45\\xdf\\xc2\\xf1\\xc6u\\xb7\\xf5\\x16f\\x0f\\..."] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level [hostname "www.um-li.xyz"] [uri "/nextcloud/apps/files/"] [unique_id ...]

[Tue Feb 14 13:08:55.093685 2023] [:error] [pid 63124] [client 127.0.0.1:39012] [client 127.0.0.1] ModSecurity: Warning. String match within "/proxy/ /lock-token/ /content-range/ /if/" at TX:header_name_if. [file "/usr/share/modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1106"] [id "920450"] [msg "HTTP header is restricted by policy (/if/)"] [data "Restricted header detected: /if/"] [severity "CRITICAL"] [ver "OWASP_CRS/3.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/210/272"] [tag "PCI/12.1"] [hostname "www.um-li.xyz"] [uri "/nextcloud/apps/files/"] [unique_id ...]

Nextcloud server version is v25.0.3.

FP when uploading image to shared folder

Since nextcloud 9.0.2.2 the following error appears in the log when trying to upload an image into a shared folder:
ModSecurity: Warning. Match of "within %{tx.allowed_request_content_type}" against "TX:content_type" required. [file "/etc/modsecurity/crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1012"] [id "920420"] [msg "Request content type is not allowed by policy"] [data "|image/jpeg|"] [severity "CRITICAL"] [ver "OWASP_CRS/4.3.0"] [tag "application-multi"] [tag "language-multi"] [tag "platform-multi"] [tag "attack-protocol"] [tag "paranoia-level/1"] [tag "OWASP_CRS"] [tag "capec/1000/255/153"] [tag "PCI/12.1"] [uri "/public.php/dav/files/Dnrmk2Bo9ymdeRJ/IMG_6671.jpeg"]

Editing an existing Nextcloud Cookbook app recipe triggers 911100 rule false positive

Here's the ModSecurity transaction log:

{
  "transaction": {
    "client_ip": "192.168.1.1",
    "time_stamp": "Sun Jul 21 17:59:16 2024",
    "server_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "client_port": 11306,
    "host_ip": "xxx.xxx.xxx.xxx",
    "host_port": 443,
    "unique_id": "xxxxxxxxxxxx.xxxxxx",
    "request": {
      "method": "PUT",
      "http_version": 2.0,
      "uri": "/apps/cookbook/webapp/recipes/108316",
      "body": "{\"id\":\"108316\",\"name\":\"white cashew sauce for gnochi?\",\"description\":\"\",\"url\":\"\",\"image\":\"\",\"prepTime\":null,\"cookTime\":null,\"totalTime\":null,\"recipeCategory\":\"\",\"keywords\":\"\",\"recipeYield\":1,\"tool\":[],\"recipeIngredient\":[\"200 g cashews\",\"1 enough boiling water to completely cover the cashews\",\"1 bay leaf\"],\"recipeInstructions\":[\"Soak the cashews in boiling water for an hour\"],\"nutrition\":{\"@type\":\"NutritionInformation\"},\"valueInit\":{\"id\":\"108316\",\"name\":\"white cashew sauce for gnochi?\",\"description\":\"\",\"url\":\"\",\"image\":\"\",\"prepTime\":null,\"cookTime\":null,\"totalTime\":null,\"recipeCategory\":\"\",\"keywords\":\"\",\"recipeYield\":1,\"tool\":[],\"recipeIngredient\":[\"200 gcashews\",\"1 enough boiling water to completely cover the cashews\"],\"recipeInstructions\":[\"Soak the cashews in boiling water for an hour\"],\"nutrition\":{\"@type\":\"NutritionInformation\"},\"valueInit\":{\"id\":0,\"name\":\"\",\"description\":\"\",\"url\":\"\",\"image\":\"\",\"prepTime\":\"\",\"cookTime\":\"\",\"totalTime\":\"\",\"recipeCategory\":\"\",\"keywords\":\"\",\"recipeYield\":\"\",\"tool\":[],\"recipeIngredient\":[],\"recipeInstructions\":[],\"nutrition\":[]},\"@context\":\"http://schema.org\",\"@type\":\"Recipe\",\"dateCreated\":\"2024-07-21T14:25:24+00:00\",\"dateModified\":\"2024-07-21T14:25:24+00:00\",\"datePublished\":null,\"printImage\":true,\"imageUrl\":\"/apps/cookbook/webapp/recipes/108316/image?size=full\"},\"@context\":\"http://schema.org\",\"@type\":\"Recipe\",\"dateCreated\":\"2024-07-21T14:25:24+00:00\",\"dateModified\":\"2024-07-21T14:25:24+00:00\",\"datePublished\":null,\"printImage\":true,\"imageUrl\":\"/apps/cookbook/webapp/recipes/108316/image?size=full\"}",
      "headers": {
        "origin": "https://cloud.example.com",
        "dnt": "1",
        "requesttoken": "U+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=",
        "x-requested-with": "XMLHttpRequest, XMLHttpRequest",
        "content-type": "application/json",
        "accept-encoding": "gzip, deflate, br",
        "cookie": "__Host-nc_sameSiteCookielax=true; __Host-nc_sameSiteCookiestrict=true; oc_sessionPassphrase=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; ocrkhwrly2jb=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "content-length": "1557",
        "accept-language": "en-US,en;q=0.5",
        "te": "trailers",
        "accept": "application/json, text/plain, */*",
        "user-agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0",
        "sec-fetch-site": "same-origin",
        "host": "cloud.example.com",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors"
      }
    },
    "response": {
      "http_code": 403,
      "headers": {
        "Server": "",
        "Date": "Sun, 21 Jul 2024 15:59:16 GMT",
        "Content-Length": "146",
        "Content-Type": "text/html",
        "Connection": "close",
        "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
      }
    },
    "producer": {
      "modsecurity": "ModSecurity v3.0.12 (Linux)",
      "connector": "ModSecurity-nginx v1.0.3",
      "secrules_engine": "Enabled",
      "components": [
        "OWASP_CRS/4.4.0\""
      ]
    },
    "messages": [
      {
        "message": "Method is not allowed by policy",
        "details": {
          "match": "Matched \"Operator `Within' with parameter `GET HEAD POST OPTIONS' against variable `REQUEST_METHOD' (Value: `PUT' )",
          "reference": "v0,3",
          "ruleId": "911100",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf",
          "lineNumber": "28",
          "data": "PUT",
          "severity": "2",
          "ver": "OWASP_CRS/4.4.0",
          "rev": "",
          "tags": [
            "application-multi",
            "language-multi",
            "platform-multi",
            "attack-generic",
            "paranoia-level/1",
            "OWASP_CRS",
            "capec/1000/210/272/220/274",
            "PCI/12.1"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      },
      {
        "message": "Inbound Anomaly Score Exceeded (Total Score: 5)",
        "details": {
          "match": "Matched \"Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `5' )",
          "reference": "",
          "ruleId": "949110",
          "file": "/etc/nginx/owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf",
          "lineNumber": "222",
          "data": "",
          "severity": "0",
          "ver": "OWASP_CRS/4.4.0",
          "rev": "",
          "tags": [
            "anomaly-evaluation",
            "OWASP_CRS"
          ],
          "maturity": "0",
          "accuracy": "0"
        }
      }
    ]
  }
}

If it's helpful, I'm running Nextcloud version 29.0.3 and Cookbook version 0.11.1. Thank you for all your help! 🙏

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.