SWW_APPS: an app's Core Rule Set fixes apply only to the hostnames that serve it (closes #220)
check / check (push) Failing after 2m47s
check / check (push) Failing after 2m47s
Each app's fixes are one .conf file, whose first rule skips the rest unless Inspect sets tx.app_<name>, and one entry in apps. SWW_APPS names each hostname's apps. A hostname gets only its apps' fixes; while SWW_APPS is unset, every hostname gets every app's fixes. A hostname in SWW_APPS that is not a DNS name, such as *.example.com, stops the start. Unset, SWW_APPS is logged at start as null; set empty, as "". Model: opus-5-5
This commit is contained in:
1 parent
c1bb813a5e
commit
2d6a91c7b1
15 files changed
+892
-358
No files matched your search
@@ -81,8 +81,8 @@ 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 eleven changes listed
|
||||
under "Attack detection", as Coraza directives.
|
||||
- `internal/coreruleset`: the Core Rule Set, with the six changes and the
|
||||
apps' fixes listed under "Attack detection", as Coraza directives.
|
||||
- `internal/lookup`: looks clients up through GeoJS or in the lookup
|
||||
database.
|
||||
- `internal/reputation`: fetches the lists, asks the DNS blocklists and
|
||||
@@ -676,8 +676,8 @@ 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 eleventh changes below hold
|
||||
gitea's, WordPress's, Drupal's and MediaWiki's.
|
||||
holds an app's own exclusions; the apps' fixes below hold gitea's,
|
||||
WordPress's, Drupal's and MediaWiki's.
|
||||
- `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
|
||||
`REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf` at the same point.
|
||||
@@ -723,9 +723,9 @@ 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 eleven ways, since in front of
|
||||
gitea, WordPress, Drupal and MediaWiki it would otherwise refuse ordinary
|
||||
requests. The changes hold in front of every app, and no setting undoes them:
|
||||
`smallwebwaf` changes the Core Rule Set 4.25.0 in six ways, since in front of
|
||||
gitea it would otherwise refuse ordinary requests. 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.
|
||||
@@ -742,8 +742,52 @@ requests. The changes hold in front of every app, and no setting undoes them:
|
||||
and tea, which gitea registers for OAuth sign-in, ask to be sent back to
|
||||
`http://127.0.0.1` on the user's own machine. The server never fetches that
|
||||
address.
|
||||
4. Ten query parameters are not checked against the Core Rule Set's lists of
|
||||
system files (930120), shell paths (932160) and command names (932260):
|
||||
4. `Referer` is not checked for a Unix command given without arguments (932340),
|
||||
for Java starting a process (944110) or for a Java class name (944130).
|
||||
`Referer` names the page a request comes from, on everything that page loads
|
||||
and on every link followed from it. The Core Rule Set takes some page
|
||||
addresses for attacks:
|
||||
- a search for `env`;
|
||||
- OpenJDK's `Runtime.java`, whose path holds both `runtime` and `java.`;
|
||||
- a file named `java.lang.String.md`.
|
||||
|
||||
Every request from such a page would be refused. `Referer` keeps the other
|
||||
rules, except after some gitea searches (gitea's fixes). An app that passes
|
||||
`Referer` to a shell must check it itself.
|
||||
|
||||
5. Responses are not inspected. A raw file from a repository, such as a shell
|
||||
script, looks to the response rules like source code leaking from the server.
|
||||
6. The `from` parameter of a container registry's upload path,
|
||||
`/v2/<image>/blobs/uploads/`, is not checked for command names (932260). When
|
||||
a push reuses a layer, `from` names the image the layer comes from. An image
|
||||
such as `owner/python3-app` would have that push refused.
|
||||
|
||||
Each supported app also has its own fixes, which let its ordinary requests
|
||||
through. `SWW_APPS` says which hostnames get which app's fixes:
|
||||
|
||||
- `SWW_APPS` holds entries separated by semicolons. Each is a hostname, a colon,
|
||||
then one or more apps separated by commas, for example
|
||||
`git.example.com:gitea;blog.example.com:wordpress`.
|
||||
- The request's `Host` is matched by exact name, without its port and without
|
||||
regard to case. There are no wildcards.
|
||||
- A hostname not listed gets no app's fixes, so every rule checks it in full.
|
||||
Set empty, `SWW_APPS` lists no hostname.
|
||||
- Unset, every app's fixes hold for every hostname. An app's fixes then weaken
|
||||
the check of any other app that serves the same paths or fields.
|
||||
- Any of these mistakes stops the start:
|
||||
- an unknown app;
|
||||
- a hostname that is not a DNS name, such as `*.example.com`;
|
||||
- a hostname listed twice;
|
||||
- an app listed twice for one hostname;
|
||||
- an entry without a colon.
|
||||
|
||||
The apps supported are `drupal`, `gitea`, `mediawiki` and `wordpress`. Each
|
||||
app's fixes are in one file, such as `internal/coreruleset/gitea.conf`, and one
|
||||
entry of `apps` in `internal/coreruleset/coreruleset.go`. gitea's fixes are:
|
||||
|
||||
1. Ten query parameters are not checked against the Core Rule Set's lists of
|
||||
system files (930120), shell paths (932160) and command names (932260), on
|
||||
any path:
|
||||
- `path`, `files`, `skip-to` and `sub_path`;
|
||||
- `ref`, `sha`, `branch` and `workflow`;
|
||||
- `artifactName` and `redirect_to`.
|
||||
@@ -756,42 +800,19 @@ requests. 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, except on the
|
||||
gitea, WordPress, Drupal and MediaWiki paths the eighth to eleventh changes
|
||||
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.
|
||||
paths named in gitea's third fix, in WordPress's fixes, in Drupal's fixes
|
||||
and in MediaWiki's fixes.
|
||||
|
||||
5. Two cookies are left out, and `Referer` keeps fewer rules:
|
||||
- The Core Rule Set reads the request without the `gitea_flash` and
|
||||
`redirect_to` cookies. gitea puts a message naming what was just done into
|
||||
`gitea_flash`. It puts into `redirect_to` the page to return to after
|
||||
signing in. The Core Rule Set takes file names in them, such as
|
||||
`package.json`, for attacks. A browser sends such a cookie with every
|
||||
request until gitea replaces it. gitea cannot replace it while those
|
||||
requests are refused, so one refusal would keep the browser out of the
|
||||
whole site. gitea shows the message with any script removed and returns
|
||||
only to its own pages. Every other cookie is read in full. An app that
|
||||
reads a cookie of either name must check it itself.
|
||||
- `Referer` is not checked for a Unix command given without arguments
|
||||
(932340), for Java starting a process (944110) or for a Java class name
|
||||
(944130). `Referer` names the page a request comes from, on everything
|
||||
that page loads and on every link followed from it. The Core Rule Set
|
||||
takes some page addresses for attacks:
|
||||
- a search for `env`;
|
||||
- OpenJDK's `Runtime.java`, whose path holds both `runtime` and `java.`;
|
||||
- a file named `java.lang.String.md`.
|
||||
|
||||
Every request from such a page would be refused. `Referer` keeps the
|
||||
other rules, except after some gitea searches (the eighth change). An
|
||||
app that passes `Referer` to a shell must check it itself.
|
||||
|
||||
6. Responses are not inspected. A raw file from a repository, such as a shell
|
||||
script, looks to the response rules like source code leaking from the server.
|
||||
7. The `from` parameter of a container registry's upload path,
|
||||
`/v2/<image>/blobs/uploads/`, is not checked for command names (932260). When
|
||||
a push reuses a layer, `from` names the image the layer comes from. An image
|
||||
such as `owner/python3-app` would have that push refused.
|
||||
8. On gitea's paths, some fields skip the rules that refused ordinary gitea
|
||||
2. The Core Rule Set reads the request without the `gitea_flash` and
|
||||
`redirect_to` cookies. gitea puts a message naming what was just done into
|
||||
`gitea_flash`. It puts into `redirect_to` the page to return to after signing
|
||||
in. The Core Rule Set takes file names in them, such as `package.json`, for
|
||||
attacks. A browser sends such a cookie with every request until gitea
|
||||
replaces it. gitea cannot replace it while those requests are refused, so one
|
||||
refusal would keep the browser out of the whole site. gitea shows the message
|
||||
with any script removed and returns only to its own pages. Every other cookie
|
||||
is read in full.
|
||||
3. On gitea's paths, some fields skip the rules that refused ordinary gitea
|
||||
requests there. They are the fields where gitea sends a search, a file name
|
||||
or a branch name. `internal/coreruleset/gitea.conf` lists each rule and the
|
||||
request it refused. The fields are:
|
||||
@@ -809,8 +830,7 @@ requests. The changes hold in front of every app, and no setting undoes them:
|
||||
- packages.
|
||||
|
||||
A user's or an organisation's page is any path of one segment, so on
|
||||
every such path, on any app, `q` skips these three rules, for example on
|
||||
`/search`.
|
||||
every such path `q` skips these three rules, for example on `/search`.
|
||||
|
||||
Some of these searches also skip the rule for Java class names (944130),
|
||||
which refused `org.apache.commons.logging`.
|
||||
@@ -848,215 +868,214 @@ requests. The changes hold in front of every app, and no setting undoes them:
|
||||
`actions/upload-artifact@v3` (920450).
|
||||
|
||||
Elsewhere these fields keep every rule. The paths are those of gitea at the
|
||||
site root. An app other than gitea that serves one of them must check these
|
||||
fields itself.
|
||||
site root.
|
||||
|
||||
9. On WordPress's paths, some fields skip the rules that refused ordinary
|
||||
WordPress requests there. `internal/coreruleset/wordpress.conf` lists each
|
||||
rule and the request it refused. The REST API has four addresses:
|
||||
- `/wp-json/...`
|
||||
- `/index.php/wp-json/...`
|
||||
- `/index.php?rest_route=/...`
|
||||
- `/?rest_route=/...`
|
||||
WordPress's fixes: on WordPress's paths, some fields skip the rules that refused
|
||||
ordinary WordPress requests there. `internal/coreruleset/wordpress.conf` lists
|
||||
each rule and the request it refused. The REST API has four addresses:
|
||||
|
||||
The fields are:
|
||||
- The header `X-HTTP-Method-Override` on any address of the REST API
|
||||
(920450). The block editor saves a post with `POST` and names `PUT` in
|
||||
this header.
|
||||
- Three groups of fields skip the rules on system files and commands
|
||||
(930120, 932120, 932250, 932260). The fields hold searches, names and
|
||||
addresses of WordPress's own pages, and any of them can hold any word. The
|
||||
groups are:
|
||||
- On all of `/wp-admin/` and on `/wp-login.php`:
|
||||
- the searches `s`, `search`, `q` and `term`;
|
||||
- the names `tag`, `category_name`, `plugin`, `checked[]`, `theme`
|
||||
and `stylesheet`;
|
||||
- the name of a plugin's settings page in `page`;
|
||||
- the addresses `url`, `return`, `redirect_to`, `wp_http_referer`
|
||||
and `_wp_http_referer`.
|
||||
- On every REST API route under `/wp/v2/` and on the route
|
||||
`/oembed/1.0/embed`: `search`, `term`, `slug` and `url`.
|
||||
- On `/`, `/index.php`, `/page/N/` and `/index.php/page/N/`: `s` and
|
||||
`tag`.
|
||||
- `/wp-json/...`
|
||||
- `/index.php/wp-json/...`
|
||||
- `/index.php?rest_route=/...`
|
||||
- `/?rest_route=/...`
|
||||
|
||||
The addresses of the first group also skip the rule on Unix commands
|
||||
(932235), because an address repeats the search it came from. The other
|
||||
fields of the groups keep that rule.
|
||||
The fields are:
|
||||
|
||||
- On all of `/wp-admin/` and on `/wp-login.php`, these names skip the lists
|
||||
of PowerShell commands and command names (932120, 932260):
|
||||
- the name of a template in `p` and `postId` of the site editor;
|
||||
- the name of a plugin to install in `slug`.
|
||||
- The header `X-HTTP-Method-Override` on any address of the REST API (920450).
|
||||
The block editor saves a post with `POST` and names `PUT` in this header.
|
||||
- Three groups of fields skip the rules on system files and commands (930120,
|
||||
932120, 932250, 932260). The fields hold searches, names and addresses of
|
||||
WordPress's own pages, and any of them can hold any word. The groups are:
|
||||
- On all of `/wp-admin/` and on `/wp-login.php`:
|
||||
- the searches `s`, `search`, `q` and `term`;
|
||||
- the names `tag`, `category_name`, `plugin`, `checked[]`, `theme` and
|
||||
`stylesheet`;
|
||||
- the name of a plugin's settings page in `page`;
|
||||
- the addresses `url`, `return`, `redirect_to`, `wp_http_referer` and
|
||||
`_wp_http_referer`.
|
||||
- On every REST API route under `/wp/v2/` and on the route
|
||||
`/oembed/1.0/embed`: `search`, `term`, `slug` and `url`.
|
||||
- On `/`, `/index.php`, `/page/N/` and `/index.php/page/N/`: `s` and `tag`.
|
||||
|
||||
WordPress writes these names as slugs, such as `htaccess` and `ls-la`.
|
||||
The addresses of the first group also skip the rule on Unix commands
|
||||
(932235), because an address repeats the search it came from. The other
|
||||
fields of the groups keep that rule.
|
||||
|
||||
- `url` on the REST API routes `/wp-block-editor/v1/url-details` and
|
||||
`/oembed/1.0/proxy`, for the lists of system files and PowerShell commands
|
||||
(930120, 932120). The block editor's link previews and embeds send an
|
||||
address in this field.
|
||||
- On all of `/wp-admin/` and on `/wp-login.php`, these names skip the lists of
|
||||
PowerShell commands and command names (932120, 932260):
|
||||
- the name of a template in `p` and `postId` of the site editor;
|
||||
- the name of a plugin to install in `slug`.
|
||||
|
||||
- `_wp_http_referer` on `/wp-admin/upload.php`, for a Unix command given
|
||||
without arguments (932340). The media list's own address ends in `&ps`.
|
||||
- `file` on `/wp-admin/plugin-editor.php` and `/wp-admin/theme-editor.php`,
|
||||
for the lists of system files, shell paths, command names and JavaScript
|
||||
names (930120, 932120, 932160, 932260, 941180).
|
||||
- These fields of a body. Each applies only when the query has no parameter
|
||||
of that name, so it matters only while `SWW_WAF_BODY_LIMIT` is set:
|
||||
- `content` of a post, a page, a template or a template part saved
|
||||
through the REST API. It holds HTML and any code it shows.
|
||||
- `content` of a reply to a comment sent to `admin-ajax.php`.
|
||||
- `newcontent` of a plugin's or a theme's file saved from its editor,
|
||||
which is PHP.
|
||||
- `pwd` when signing in, for the list of system files (930120).
|
||||
- `title`, `excerpt` and `name` in a JSON body sent to any REST API
|
||||
route under `/wp/v2/`, for the rules on system files and commands
|
||||
(930120, 932120, 932250, 932260).
|
||||
- `slug` in a JSON body sent to any REST API route under `/wp/v2/`, for
|
||||
the lists of PowerShell commands and command names (932120, 932260).
|
||||
- `url` on `/wp-comments-post.php`, the address of a commenter's site,
|
||||
for the lists of system files and PowerShell commands (930120,
|
||||
932120).
|
||||
WordPress writes these names as slugs, such as `htaccess` and `ls-la`.
|
||||
|
||||
Elsewhere this change does not apply. The paths are those of WordPress at
|
||||
the site root. An app other than WordPress that serves one of them must
|
||||
check these fields itself.
|
||||
- `url` on the REST API routes `/wp-block-editor/v1/url-details` and
|
||||
`/oembed/1.0/proxy`, for the lists of system files and PowerShell commands
|
||||
(930120, 932120). The block editor's link previews and embeds send an address
|
||||
in this field.
|
||||
|
||||
10. On Drupal's paths, some fields skip the rules that refused ordinary Drupal
|
||||
requests there. `internal/coreruleset/drupal.conf` lists each rule and the
|
||||
request it refused. These query fields skip the lists of system files and
|
||||
command names (930120, 932120, 932250, 932260):
|
||||
- On every page under `/admin`: `title`, `name`, `user`, `filename`,
|
||||
`filemime`, `info`, `subject`, `author_name`, `search`, `q` and
|
||||
`destination`.
|
||||
- `destination` on the pages Drupal links to with one, such as these:
|
||||
- `/node/1/edit`;
|
||||
- `/user/login`;
|
||||
- `/node/1/revisions/2/revert`;
|
||||
- `/block/add/basic`;
|
||||
- `/big_pipe/no-js`.
|
||||
- `keys` on `/search` and the pages under it.
|
||||
- `q` on these autocompletes:
|
||||
- `/entity_reference_autocomplete/`;
|
||||
- `/ckeditor5/{editor}/entity-link-suggestions`;
|
||||
- `/block-category/autocomplete`.
|
||||
- Every `filter[...]` field on `/jsonapi/`.
|
||||
- `name` on `/user/password`, `/media-library` and `/views/ajax`, in the
|
||||
query or a body.
|
||||
- `_wp_http_referer` on `/wp-admin/upload.php`, for a Unix command given without
|
||||
arguments (932340). The media list's own address ends in `&ps`.
|
||||
- `file` on `/wp-admin/plugin-editor.php` and `/wp-admin/theme-editor.php`, for
|
||||
the lists of system files, shell paths, command names and JavaScript names
|
||||
(930120, 932120, 932160, 932260, 941180).
|
||||
- These fields of a body. Each applies only when the query has no parameter of
|
||||
that name, so it matters only while `SWW_WAF_BODY_LIMIT` is set:
|
||||
- `content` of a post, a page, a template or a template part saved through
|
||||
the REST API. It holds HTML and any code it shows.
|
||||
- `content` of a reply to a comment sent to `admin-ajax.php`.
|
||||
- `newcontent` of a plugin's or a theme's file saved from its editor, which
|
||||
is PHP.
|
||||
- `pwd` when signing in, for the list of system files (930120).
|
||||
- `title`, `excerpt` and `name` in a JSON body sent to any REST API route
|
||||
under `/wp/v2/`, for the rules on system files and commands (930120,
|
||||
932120, 932250, 932260).
|
||||
- `slug` in a JSON body sent to any REST API route under `/wp/v2/`, for the
|
||||
lists of PowerShell commands and command names (932120, 932260).
|
||||
- `url` on `/wp-comments-post.php`, the address of a commenter's site, for
|
||||
the lists of system files and PowerShell commands (930120, 932120).
|
||||
|
||||
`destination` also skips 932230 and 932235, because it holds the address of
|
||||
a page of results. `url` on `/media/oembed`, the address of a video, skips
|
||||
only 930120 and 932120.
|
||||
Elsewhere WordPress's fixes do not apply. The paths are those of WordPress at
|
||||
the site root.
|
||||
|
||||
These fields of a body skip the rules that refused them:
|
||||
- On the node, comment and media forms, for 930120, 932120, 932250 and
|
||||
932260:
|
||||
- the title;
|
||||
- the summary;
|
||||
- the tags;
|
||||
- the address;
|
||||
- the revision note;
|
||||
- the comment subject;
|
||||
- the media name;
|
||||
- the image text.
|
||||
- On the tag, custom block and contact forms, for the same four rules:
|
||||
- the tag's name and description;
|
||||
- the block description and body;
|
||||
- the subject and message of a contact message.
|
||||
- These fields through JSON:API, for the same four rules:
|
||||
- `title`;
|
||||
- `subject`;
|
||||
- `body.summary`;
|
||||
- `name`;
|
||||
- `revision_log`;
|
||||
- `info`;
|
||||
- `description.value`.
|
||||
- The title saved through Drupal's JSON format on `/node/{id}`, for the same
|
||||
four rules.
|
||||
- The body and comment body on the node and comment forms and through
|
||||
JSON:API, which hold HTML and any code it shows.
|
||||
- `name` and `pass` when signing in (930120, 932120, 932250, 932260).
|
||||
- `name` when resetting a password through Drupal's JSON format on
|
||||
`/user/password`, for the same four rules.
|
||||
- `name` when signing up, editing an account and commenting without an
|
||||
account, for the same four rules.
|
||||
- `mail` on those forms, for 930120, 932120 and 932260 only.
|
||||
Drupal's fixes: on Drupal's paths, some fields skip the rules that refused
|
||||
ordinary Drupal requests there. `internal/coreruleset/drupal.conf` lists each
|
||||
rule and the request it refused. These query fields skip the lists of system
|
||||
files and command names (930120, 932120, 932250, 932260):
|
||||
|
||||
These exclusions matter only while `SWW_WAF_BODY_LIMIT` is set. None applies
|
||||
when the query has a parameter of the same name.
|
||||
- On every page under `/admin`: `title`, `name`, `user`, `filename`, `filemime`,
|
||||
`info`, `subject`, `author_name`, `search`, `q` and `destination`.
|
||||
- `destination` on the pages Drupal links to with one, such as these:
|
||||
- `/node/1/edit`;
|
||||
- `/user/login`;
|
||||
- `/node/1/revisions/2/revert`;
|
||||
- `/block/add/basic`;
|
||||
- `/big_pipe/no-js`.
|
||||
- `keys` on `/search` and the pages under it.
|
||||
- `q` on these autocompletes:
|
||||
- `/entity_reference_autocomplete/`;
|
||||
- `/ckeditor5/{editor}/entity-link-suggestions`;
|
||||
- `/block-category/autocomplete`.
|
||||
- Every `filter[...]` field on `/jsonapi/`.
|
||||
- `name` on `/user/password`, `/media-library` and `/views/ajax`, in the query
|
||||
or a body.
|
||||
|
||||
Elsewhere these fields keep every rule. The paths are those of Drupal at the
|
||||
site root, with or without a language prefix such as `/fr`. Such a prefix is
|
||||
any first path segment of two or three lowercase letters, optionally
|
||||
followed by a hyphen and more letters, so `/api` counts too. An app other
|
||||
than Drupal that serves one of them must check these fields itself.
|
||||
`destination` also skips 932230 and 932235, because it holds the address of a
|
||||
page of results. `url` on `/media/oembed`, the address of a video, skips only
|
||||
930120 and 932120.
|
||||
|
||||
11. On MediaWiki's paths, some fields skip the rules that refused ordinary
|
||||
MediaWiki requests there. `internal/coreruleset/mediawiki.conf` lists each
|
||||
rule and the request it refused. These fields skip the lists of system files
|
||||
and command names (930120, 932120, 932250, 932260), in the query or the
|
||||
body:
|
||||
- On MediaWiki's pages, which are `/index.php` and the paths under
|
||||
`/index.php/` and `/wiki/`:
|
||||
- the searches `search` and `ilsearch`;
|
||||
- the titles `title`, `page` and `target`;
|
||||
- `from`, `to` and `prefix`, which limit a list of pages;
|
||||
- the user names `user`, `username` and `wpTarget`;
|
||||
- the file names `filename` and `wpDestFile`;
|
||||
- `returnto` and `returntoquery`, the page and query to go back to after
|
||||
signing in.
|
||||
- On `/api.php`:
|
||||
- the searches `search`, `srsearch` and `pssearch`;
|
||||
- the titles `titles`, `title`, `page` and `bltitle`;
|
||||
- `from` and `to`, the titles of a page being moved;
|
||||
- the starts of lists `apfrom`, `apto`, `apprefix`, `aifrom`,
|
||||
`aiprefix`, `aufrom` and `auprefix`;
|
||||
- `gsrsearch`, `gpssearch`, `gapfrom` and `gbltitle`, which a generator
|
||||
sends in place of `srsearch`, `pssearch`, `apfrom` and `bltitle`;
|
||||
- `euquery`, an address;
|
||||
- the user names `ucuser`, `bkusers` and `user`;
|
||||
- `summary`, `sectiontitle`, `filename`, `comment` and `reason`;
|
||||
- `lgname`, `lgpassword`, `username` and `password`, for signing in.
|
||||
- `q` on `/rest.php/` and the paths under it.
|
||||
These fields of a body skip the rules that refused them:
|
||||
|
||||
`modules` on `/load.php` skips 930120 alone, because it lists the scripts
|
||||
and styles a page loads.
|
||||
- On the node, comment and media forms, for 930120, 932120, 932250 and 932260:
|
||||
- the title;
|
||||
- the summary;
|
||||
- the tags;
|
||||
- the address;
|
||||
- the revision note;
|
||||
- the comment subject;
|
||||
- the media name;
|
||||
- the image text.
|
||||
- On the tag, custom block and contact forms, for the same four rules:
|
||||
- the tag's name and description;
|
||||
- the block description and body;
|
||||
- the subject and message of a contact message.
|
||||
- These fields through JSON:API, for the same four rules:
|
||||
- `title`;
|
||||
- `subject`;
|
||||
- `body.summary`;
|
||||
- `name`;
|
||||
- `revision_log`;
|
||||
- `info`;
|
||||
- `description.value`.
|
||||
- The title saved through Drupal's JSON format on `/node/{id}`, for the same
|
||||
four rules.
|
||||
- The body and comment body on the node and comment forms and through JSON:API,
|
||||
which hold HTML and any code it shows.
|
||||
- `name` and `pass` when signing in (930120, 932120, 932250, 932260).
|
||||
- `name` when resetting a password through Drupal's JSON format on
|
||||
`/user/password`, for the same four rules.
|
||||
- `name` when signing up, editing an account and commenting without an account,
|
||||
for the same four rules.
|
||||
- `mail` on those forms, for 930120, 932120 and 932260 only.
|
||||
|
||||
These fields of a body skip the rules that refused them:
|
||||
- On MediaWiki's pages, for the same four rules:
|
||||
- `wpSummary`, the summary of an edit;
|
||||
- `wpUploadDescription`, the description of an uploaded file;
|
||||
- `wpName` and `wpPassword`, for signing in;
|
||||
- `wpOldTitle`, `wpNewTitleMain` and `wpReason`, for moving a page.
|
||||
- `comment` in the JSON body of `/rest.php/`, for the same four rules.
|
||||
- On MediaWiki's pages, for 930120 and 932120 alone, the reasons on the
|
||||
admin pages:
|
||||
- `wpReason-other`, for blocking a user;
|
||||
- `user-reason`, for changing a user's groups;
|
||||
- `mwProtect-reason`, for protecting a page.
|
||||
- The wikitext of a page, which holds templates, tables and any code it
|
||||
shows:
|
||||
- `wpTextbox1` on MediaWiki's pages;
|
||||
- `text`, `appendtext` and `prependtext` on `/api.php`;
|
||||
- `source` in the JSON body of `/rest.php/`.
|
||||
These exclusions matter only while `SWW_WAF_BODY_LIMIT` is set. None applies
|
||||
when the query has a parameter of the same name.
|
||||
|
||||
These body exclusions matter only while `SWW_WAF_BODY_LIMIT` is set. None
|
||||
applies when the query has a parameter of the same name.
|
||||
Elsewhere these fields keep every rule. The paths are those of Drupal at the
|
||||
site root, with or without a language prefix such as `/fr`. Such a prefix is any
|
||||
first path segment of two or three lowercase letters, optionally followed by a
|
||||
hyphen and more letters, so `/api` counts too.
|
||||
|
||||
The names of uploaded files skip 932180 on MediaWiki's pages and on
|
||||
`/api.php`, so a picture named `Notes on .htaccess.png` can be uploaded.
|
||||
MediaWiki refuses a file whose extension it does not allow.
|
||||
MediaWiki's fixes: on MediaWiki's paths, some fields skip the rules that refused
|
||||
ordinary MediaWiki requests there. `internal/coreruleset/mediawiki.conf` lists
|
||||
each rule and the request it refused. These fields skip the lists of system
|
||||
files and command names (930120, 932120, 932250, 932260), in the query or the
|
||||
body:
|
||||
|
||||
`/index.php` itself counts as MediaWiki's only when its query has a `title`,
|
||||
as in `/index.php?title=Main_Page`. WordPress serves `/index.php` too. A
|
||||
wiki without short URLs serves its pages under `/index.php/`, as in
|
||||
`/index.php/Main_Page`, and its sign-in and upload forms post there.
|
||||
- On MediaWiki's pages, which are `/index.php` and the paths under `/index.php/`
|
||||
and `/wiki/`:
|
||||
- the searches `search` and `ilsearch`;
|
||||
- the titles `title`, `page` and `target`;
|
||||
- `from`, `to` and `prefix`, which limit a list of pages;
|
||||
- the user names `user`, `username` and `wpTarget`;
|
||||
- the file names `filename` and `wpDestFile`;
|
||||
- `returnto` and `returntoquery`, the page and query to go back to after
|
||||
signing in.
|
||||
- On `/api.php`:
|
||||
- the searches `search`, `srsearch` and `pssearch`;
|
||||
- the titles `titles`, `title`, `page` and `bltitle`;
|
||||
- `from` and `to`, the titles of a page being moved;
|
||||
- the starts of lists `apfrom`, `apto`, `apprefix`, `aifrom`, `aiprefix`,
|
||||
`aufrom` and `auprefix`;
|
||||
- `gsrsearch`, `gpssearch`, `gapfrom` and `gbltitle`, which a generator
|
||||
sends in place of `srsearch`, `pssearch`, `apfrom` and `bltitle`;
|
||||
- `euquery`, an address;
|
||||
- the user names `ucuser`, `bkusers` and `user`;
|
||||
- `summary`, `sectiontitle`, `filename`, `comment` and `reason`;
|
||||
- `lgname`, `lgpassword`, `username` and `password`, for signing in.
|
||||
- `q` on `/rest.php/` and the paths under it.
|
||||
|
||||
Elsewhere these fields keep every rule. The paths are those of MediaWiki at
|
||||
the site root or under `/w/`. An app other than MediaWiki that serves one of
|
||||
them must check these fields itself.
|
||||
`modules` on `/load.php` skips 930120 alone, because it lists the scripts and
|
||||
styles a page loads.
|
||||
|
||||
The parameter and cookie names in these changes are matched without regard to
|
||||
case, as Coraza matches them.
|
||||
These fields of a body skip the rules that refused them:
|
||||
|
||||
- On MediaWiki's pages, for the same four rules:
|
||||
- `wpSummary`, the summary of an edit;
|
||||
- `wpUploadDescription`, the description of an uploaded file;
|
||||
- `wpName` and `wpPassword`, for signing in;
|
||||
- `wpOldTitle`, `wpNewTitleMain` and `wpReason`, for moving a page.
|
||||
- `comment` in the JSON body of `/rest.php/`, for the same four rules.
|
||||
- On MediaWiki's pages, for 930120 and 932120 alone, the reasons on the admin
|
||||
pages:
|
||||
- `wpReason-other`, for blocking a user;
|
||||
- `user-reason`, for changing a user's groups;
|
||||
- `mwProtect-reason`, for protecting a page.
|
||||
- The wikitext of a page, which holds templates, tables and any code it shows:
|
||||
- `wpTextbox1` on MediaWiki's pages;
|
||||
- `text`, `appendtext` and `prependtext` on `/api.php`;
|
||||
- `source` in the JSON body of `/rest.php/`.
|
||||
|
||||
These body exclusions matter only while `SWW_WAF_BODY_LIMIT` is set. None
|
||||
applies when the query has a parameter of the same name.
|
||||
|
||||
The names of uploaded files skip 932180 on MediaWiki's pages and on `/api.php`,
|
||||
so a picture named `Notes on .htaccess.png` can be uploaded. MediaWiki refuses a
|
||||
file whose extension it does not allow.
|
||||
|
||||
`/index.php` itself counts as MediaWiki's only when its query has a `title`, as
|
||||
in `/index.php?title=Main_Page`. WordPress serves `/index.php` too. A wiki
|
||||
without short URLs serves its pages under `/index.php/`, as in
|
||||
`/index.php/Main_Page`, and its sign-in and upload forms post there.
|
||||
|
||||
Elsewhere these fields keep every rule. The paths are those of MediaWiki at the
|
||||
site root or under `/w/`.
|
||||
|
||||
On a hostname that gets an app's fixes, any other app there must check those
|
||||
fields and cookies itself. Listing each hostname's own apps in `SWW_APPS` keeps
|
||||
the full check for the others.
|
||||
|
||||
The parameter names in these changes and fixes are matched without regard to
|
||||
case, and the cookie names exactly.
|
||||
|
||||
### Ban lengths, response and scope
|
||||
|
||||
|
||||
Reference in new issue
Block a user