Core Rule Set: Nextcloud's ordinary requests pass by default (closes #240)
check / check (push) Failing after 5m5s

Adds nextcloud.conf, the thirteenth change. Nextcloud's WebDAV paths allow
PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, REPORT, SEARCH, LOCK and UNLOCK. The
account-name cookie nc_username, and the fields that carry a search, a name, a
file name or a folder on the sign-in page, the Files app, public shares and the
OCS API, skip the four rules that read them as commands or system files.
Comments, a share's note, a status and a document's text also skip the rules
that refused ordinary sentences, and the document the two that refused a shell
code block, so "; wget" reaches Nextcloud there. Requests recorded from
Nextcloud 35.0.2, its web pages, sync client 3.16.7 and the OCS API pass at the
defaults and while bodies are read.

Model: opus-5-5
This commit is contained in:
sneak committed 2026-11-10 05:17:09 +00:00
1 parent 20e4b3b080
commit d442848cf8
9 files changed
+2189 -46

No files matched your search

+18 -6
View File
@@ -1,6 +1,6 @@
// Package coreruleset runs the OWASP Core Rule Set 4.25.0, through Coraza, on the
// method, the URL with its query and the headers of a request, and on its
// body while SWW_WAF_BODY_LIMIT is set, with the twelve changes sww
// body while SWW_WAF_BODY_LIMIT is set, with the thirteen changes sww
// makes to it and the exclusions in SWW_CORE_RULE_SET_EXCLUSIONS_FILE, as
// "Attack detection" under "Settings" in SPEC.md describes them. It reads no
// response.
@@ -34,8 +34,9 @@ import (
// paranoia level for %d, bodyDirectives for the first %s while
// SWW_WAF_BODY_LIMIT is set, the exclusions file for the second,
// giteaExclusions for the third, wordpressExclusions for the fourth,
// drupalExclusions for the fifth, mediawikiExclusions for the sixth, and
// mastodonExclusions for the seventh.
// drupalExclusions for the fifth, mediawikiExclusions for the sixth,
// mastodonExclusions for the seventh, and nextcloudExclusions for the
// eighth.
// Each rule sww adds has an id from 900000 to 900999, the ids the
// Core Rule Set keeps for the rules that set it up, which
// SWW_WAF_DISABLED_RULES and the exclusions file refuse, so that no
@@ -95,7 +96,10 @@ SecRule ARGUMENTS_LIMIT_REACHED "@eq 1" "id:900300,phase:2,pass,\
# So does the eleventh.
%s
# And the twelfth.
# So does the twelfth.
%s
# And the thirteenth.
%s
# The sixth: only the rules for requests are loaded, and no response is
@@ -217,6 +221,14 @@ var mediawikiExclusions string
//go:embed mastodon.conf
var mastodonExclusions string
// nextcloudExclusions are the thirteenth change: the fields of Nextcloud's
// own requests that skip the rules that refused them there, the WebDAV
// methods it uses, and its cookie of the account's name, as Coraza
// directives.
//
//go:embed nextcloud.conf
var nextcloudExclusions string
// cookiesNotRead are the cookies the Core Rule Set reads a request
// without, the rest of the fifth change.
//
@@ -330,7 +342,7 @@ type CoreRuleSet struct {
bodyLimit int64
}
// New returns the Core Rule Set with the twelve changes, at params'
// New returns the Core Rule Set with the thirteen changes, at params'
// paranoia level, without the rules it switches off, reading request
// bodies up to params' limit, and with params' exclusions file loaded
// before the Core Rule Set's rules. An exclusions file is an error if it
@@ -359,7 +371,7 @@ func New(params Params) (*CoreRuleSet, error) {
text := fmt.Sprintf(directives, params.ParanoiaLevel, body, exclusions,
giteaExclusions, wordpressExclusions, drupalExclusions,
mediawikiExclusions, mastodonExclusions)
mediawikiExclusions, mastodonExclusions, nextcloudExclusions)
if len(params.DisabledRules) > 0 {
ids := make([]string, len(params.DisabledRules))