Core Rule Set: Ghost's ordinary requests pass by default (closes #357)
check / check (push) Waiting to run
check / check (push) Waiting to run
Ghost 6.76.0's ordinary traffic, recorded in `testdata/ghost-requests.txt`, passes at the default settings and while bodies are read. It covers public pages, members' sign-up and sign-in, the admin, the editor saving and publishing posts and pages with code blocks and HTML cards, tags, settings, staff invitations, uploads, newsletter settings, and both APIs. The new `ghost.conf`, the sixteenth change, lets through `filter`, the member `search` and the embed `url` in the query, and plain text, addresses, articles, code injection and passwords in JSON bodies. A `<script>` element and a `javascript:` link stay refused in articles and code injection. `README.md` lists Ghost; `SPEC.md` lists the change. Model: opus-5-5
This commit is contained in:
1 parent
63e58e326b
commit
2517912cfb
8 files changed
+1523
-14
No files matched your search
@@ -84,7 +84,7 @@ never as a time.
|
||||
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 fifteen changes listed
|
||||
- `internal/coreruleset`: the Core Rule Set, with the sixteen changes listed
|
||||
under "Attack detection", as Coraza directives.
|
||||
- `internal/lookup`: looks clients up through GeoJS or in the lookup
|
||||
database.
|
||||
@@ -681,7 +681,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 fifteenth changes below hold
|
||||
holds an app's own exclusions. The eighth to sixteenth changes below hold
|
||||
those of the apps they name.
|
||||
- `waf` loads the file after `smallwebwaf`'s own setup rules and before the
|
||||
Core Rule Set's rules. The Core Rule Set loads its own
|
||||
@@ -728,7 +728,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 fifteen ways. Without them, it
|
||||
`smallwebwaf` changes the Core Rule Set 4.25.0 in sixteen ways. Without them, it
|
||||
would refuse ordinary requests to these apps:
|
||||
|
||||
- gitea;
|
||||
@@ -738,7 +738,8 @@ would refuse ordinary requests to these apps:
|
||||
- MediaWiki;
|
||||
- Mastodon;
|
||||
- Vaultwarden;
|
||||
- Nextcloud.
|
||||
- Nextcloud;
|
||||
- Ghost.
|
||||
|
||||
The changes hold in front of every app, and no setting undoes them:
|
||||
|
||||
@@ -774,7 +775,7 @@ 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
|
||||
fifteenth changes switch some of them off for some fields on the paths of
|
||||
sixteenth 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.
|
||||
@@ -1624,6 +1625,82 @@ The changes hold in front of every app, and no setting undoes them:
|
||||
These paths are matched at the site root. An app other than Forgejo that
|
||||
serves one of them must check `q` and `Referer` itself.
|
||||
|
||||
16. On Ghost's paths, some fields skip the rules that refused ordinary Ghost
|
||||
requests there. `internal/coreruleset/ghost.conf` lists each rule and the
|
||||
request it refused. Ghost's admin and integrations call the Admin API under
|
||||
`/ghost/api/admin/`. Themes and Ghost's scripts call the Content API under
|
||||
`/ghost/api/content/`, and members call `/members/api/`.
|
||||
|
||||
Three query fields skip some rules:
|
||||
- `filter`, a query in Ghost's own filter language, skips 932120 on the
|
||||
Admin API and the Content API, so `tag:powershell` passes;
|
||||
- `search`, a search for a member, skips 930120, 932120, 932250 and 932260
|
||||
on the Admin API;
|
||||
- `url`, the address the editor looks up for an embed or a bookmark, skips
|
||||
930120 and 932120.
|
||||
|
||||
The fields of JSON bodies where a person types plain text skip 930120,
|
||||
932120, 932125, 932230, 932250, 932260 and 932380. They are these fields of
|
||||
posts, pages, tags, labels, members, newsletters and snippets, on the Admin
|
||||
API:
|
||||
- `title`, `name` and `slug`;
|
||||
- a post's `tags` and a member's `labels`, by name or slug;
|
||||
- `custom_excerpt`, `description`, `note` and `sender_name`;
|
||||
- the `meta_`, `og_` and `twitter_` titles and descriptions.
|
||||
|
||||
A member's `name` at `/members/api/` skips them too. A member's `email`
|
||||
skips 930120, 932120 and 932260, at `/members/api/` and when the admin adds
|
||||
or edits a member. A staff user's address skips them too: `username` when
|
||||
signing in, and `email` when creating the first staff user, asking for a
|
||||
password reset or saving a profile.
|
||||
|
||||
The articles carry HTML on purpose. These fields on the Admin API hold them:
|
||||
- `lexical`, which the editor saves, and `mobiledoc` and `html`, which
|
||||
integrations send, for posts and pages;
|
||||
- `lexical` and `mobiledoc` of snippets;
|
||||
- `footer_content` of newsletters.
|
||||
|
||||
The articles skip these rules:
|
||||
- 930120, 932120, 932125, 932160, 932230, 932235, 932250, 932260, 932370 and
|
||||
932380, which refused commands in a code block;
|
||||
- 934100, 941180 and 941390, which refused JavaScript in a code block;
|
||||
- 942190, which refused an SQL query in a code block;
|
||||
- 941100, 941120 and 941160, which refused an HTML card.
|
||||
|
||||
Code injection is the HTML that Ghost adds to the head and the foot of a
|
||||
page. These fields on the Admin API hold it:
|
||||
- `codeinjection_head` and `codeinjection_foot` of posts and pages;
|
||||
- `value` of settings, since the site's settings hold its code injection.
|
||||
|
||||
Code injection skips these rules:
|
||||
- 930120, 932120, 932125, 932230, 932250, 932260 and 932380, as plain text
|
||||
does;
|
||||
- 921130, 941100, 941160 and 941270, which refused `<meta>` and `<link>`
|
||||
elements.
|
||||
|
||||
`<script>alert(1)</script>` and `javascript:alert(1)` are still refused in
|
||||
the articles and code injection (941110, 941170 and 941210). Path traversal
|
||||
and SQL injection are still refused in every field above. Script injection
|
||||
is too, outside the articles. `; wget http://example.com/x.sh` is still
|
||||
refused in the query fields, the plain text and the addresses.
|
||||
|
||||
Coraza names a staff user's `profile_image` field
|
||||
`json.users.0.profile_image`. That name holds `.profile`, a file on the list
|
||||
of system files, so the name skips 930120 when a profile is saved.
|
||||
|
||||
The passwords skip each rule that random passwords set off. The numbers are
|
||||
in `internal/coreruleset/ghost.conf`. They are `password` when signing in,
|
||||
and the passwords sent when creating the first staff user, accepting an
|
||||
invitation, and resetting or changing a password. `' OR '1'='1`,
|
||||
`../../etc/passwd`, `; cat /etc/passwd` and `<img src=x onerror=x()>` sent
|
||||
as a password reach Ghost; `<script>alert(1)</script>` and
|
||||
`javascript:alert(1)` are still refused.
|
||||
|
||||
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 Ghost at the site root. An
|
||||
app other than Ghost that serves one of them must check these fields itself.
|
||||
|
||||
The parameter and cookie names in these changes are matched without regard to
|
||||
case, as Coraza matches them.
|
||||
|
||||
|
||||
Reference in new issue
Block a user