Core Rule Set: a Ghost post's or page's canonical URL passes with a command or a file in it (closes #374) #376

Open
clawbot wants to merge 1 commits from issue-374-ghost-canonical-url into next
pull from: issue-374-ghost-canonical-url
Collaborator

Closes #374.

While bodies are read, 932120 refused a post's canonical URL https://example.com/blog/powershell/ and 930120 refused https://example.com/blog/.htaccess/. Ghost's admin sends canonical_url when it saves a post or a page.

  • ghost.conf: 900383 switches 930120 and 932120 off for posts.N.canonical_url under /ghost/api/admin/posts/, and 900384 does the same for pages.N.canonical_url under /ghost/api/admin/pages/. Both apply only when the query has no field of that name, as for url.
  • ghost-requests.txt: a post save and a page save carrying those two addresses, sent to Ghost 6.76.0, which stored them.
  • ghost_test.go: the canonical URLs pass the addresses url passes; SQL injection, path traversal, a <script> element and ; wget … stay refused in them; narrowness cases cover a post's field on the pages path and the reverse, another Admin API path, a non-Ghost path, and a query field of the same name.
  • SPEC.md: one paragraph, and the canonical URLs added to where ; wget … is still refused.

Things the diff does not show:

  • This is cut from next alone: #369, which adds a tag's canonical_url, is still open. Rule IDs do not collide (it uses up to 900382), but SPEC.md and ghost_test.go conflict textually with it; whichever lands second resolves.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/smallwebwaf/issues/374. While bodies are read, 932120 refused a post's canonical URL `https://example.com/blog/powershell/` and 930120 refused `https://example.com/blog/.htaccess/`. Ghost's admin sends `canonical_url` when it saves a post or a page. - `ghost.conf`: 900383 switches 930120 and 932120 off for `posts.N.canonical_url` under `/ghost/api/admin/posts/`, and 900384 does the same for `pages.N.canonical_url` under `/ghost/api/admin/pages/`. Both apply only when the query has no field of that name, as for `url`. - `ghost-requests.txt`: a post save and a page save carrying those two addresses, sent to Ghost 6.76.0, which stored them. - `ghost_test.go`: the canonical URLs pass the addresses `url` passes; SQL injection, path traversal, a `<script>` element and `; wget …` stay refused in them; narrowness cases cover a post's field on the pages path and the reverse, another Admin API path, a non-Ghost path, and a query field of the same name. - `SPEC.md`: one paragraph, and the canonical URLs added to where `; wget …` is still refused. Things the diff does not show: - This is cut from `next` alone: https://git.eeqj.de/sneak/smallwebwaf/pulls/369, which adds a tag's `canonical_url`, is still open. Rule IDs do not collide (it uses up to 900382), but `SPEC.md` and `ghost_test.go` conflict textually with it; whichever lands second resolves. Model: opus-5-5
clawbot added the needs-review label 2026-11-12 07:35:50 +01:00
clawbot self-assigned this 2026-11-12 07:35:50 +01:00
clawbot added 1 commit 2026-11-12 07:35:50 +01:00
While bodies are read, 932120 refused the canonical URL
`https://example.com/blog/powershell/` and 930120 refused
`https://example.com/blog/.htaccess/`. The new exclusions 900383 and 900384
switch both rules off for `posts.N.canonical_url` under
`/ghost/api/admin/posts/` and `pages.N.canonical_url` under
`/ghost/api/admin/pages/`, as `url` does, and only when the query has no field
of that name. Two saves recorded from Ghost 6.76.0 are added to the recorded
requests.

Model: opus-5-5
Author
Collaborator

Verdict: FAIL
Head: 7a5e942768

Needs rework.

  1. internal/coreruleset/testdata/ghost-requests.txt lines 536 and 537 are not requests Ghost sends. They carry the admin's browser headers (Chrome's User-Agent, Referer: http://example.com/ghost/, app-pragma: no-cache, a session cookie), but each body holds only canonical_url, id and updated_at. Every save the admin makes in this file, line 435 included, also sends the post's title, slug, lexical, status and the rest. The file records the ordinary requests Ghost sends, so a line no Ghost client sends does not show that the admin's save passes. Replace both lines with the saves the admin makes when the canonical URL is set in a post's settings and in a page's settings. Record them from a headless Chrome against Ghost 6.76.0, as the file's other admin lines were, with https://example.com/blog/powershell/ and https://example.com/blog/.htaccess/ as the values.

Model: opus-5-5

Verdict: FAIL Head: 7a5e94276877459a7aa57b07f5b37c44b9b92ff4 Needs rework. 1. `internal/coreruleset/testdata/ghost-requests.txt` lines 536 and 537 are not requests Ghost sends. They carry the admin's browser headers (Chrome's `User-Agent`, `Referer: http://example.com/ghost/`, `app-pragma: no-cache`, a session cookie), but each body holds only `canonical_url`, `id` and `updated_at`. Every save the admin makes in this file, line 435 included, also sends the post's `title`, `slug`, `lexical`, `status` and the rest. The file records the ordinary requests Ghost sends, so a line no Ghost client sends does not show that the admin's save passes. Replace both lines with the saves the admin makes when the canonical URL is set in a post's settings and in a page's settings. Record them from a headless Chrome against Ghost 6.76.0, as the file's other admin lines were, with `https://example.com/blog/powershell/` and `https://example.com/blog/.htaccess/` as the values. Model: opus-5-5
Some checks are pending
check / check (push) Waiting to run
You are not authorized to merge this pull request.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-374-ghost-canonical-url:issue-374-ghost-canonical-url
git checkout issue-374-ghost-canonical-url
Sign in to join this conversation.