Core Rule Set: the searches of the pages gitea and Forgejo share pass (closes #352) #364

Open
clawbot wants to merge 1 commits from issue-352-shared-searches into next
pull from: issue-352-shared-searches
Collaborator

Closes #352.

gitea 1.27.3 and Forgejo 17.0.1, images pinned by digest, were sent every search on the shared pages that #350 lists. Each search used python3, powershell, ls -la, .htaccess, file names and plain words. Some pages also got /bin/sh, org.apache.commons.logging or SELECT * FROM users WHERE. The requests are in testdata/gitea-requests.txt and testdata/forgejo-requests.txt.

Changes in internal/coreruleset/gitea.conf:

  • 900600 and 900601, the searches of issues and pull requests, now also cover those of one team and of one milestone.
  • 900602, the searches for a name, now also covers a repository's packages page and the admin packages page.
  • 900603, where q skips only 930120, 932120, 932250 and 932260, now covers the other refused searches, which SPEC.md lists. They include the admin lists under /-/admin/ (gitea) and /admin/ (Forgejo), and the bodies of the forms that adopt a repository or activate an email.
  • 900605 now also lets /bin/sh through in q on the tags page and the repository and admin packages pages: tag and package names can hold a slash.

Not visible in the diff:

  • The pages that already passed, such as /pulls and /repo/search, are recorded with no exclusion added.
  • Disclosure: a script sent the requests with an ordinary Chrome's headers and each form's fields. Each answered 200, or 303 for the two admin forms.
  • An ordinary request can still be refused on a field outside these searches.

Model: opus-5-5

Closes https://git.eeqj.de/sneak/smallwebwaf/issues/352. gitea 1.27.3 and Forgejo 17.0.1, images pinned by digest, were sent every search on the shared pages that https://git.eeqj.de/sneak/smallwebwaf/issues/350 lists. Each search used `python3`, `powershell`, `ls -la`, `.htaccess`, file names and plain words. Some pages also got `/bin/sh`, `org.apache.commons.logging` or `SELECT * FROM users WHERE`. The requests are in `testdata/gitea-requests.txt` and `testdata/forgejo-requests.txt`. Changes in `internal/coreruleset/gitea.conf`: - 900600 and 900601, the searches of issues and pull requests, now also cover those of one team and of one milestone. - 900602, the searches for a name, now also covers a repository's packages page and the admin packages page. - 900603, where `q` skips only 930120, 932120, 932250 and 932260, now covers the other refused searches, which `SPEC.md` lists. They include the admin lists under `/-/admin/` (gitea) and `/admin/` (Forgejo), and the bodies of the forms that adopt a repository or activate an email. - 900605 now also lets `/bin/sh` through in `q` on the tags page and the repository and admin packages pages: tag and package names can hold a slash. Not visible in the diff: - The pages that already passed, such as `/pulls` and `/repo/search`, are recorded with no exclusion added. - Disclosure: a script sent the requests with an ordinary Chrome's headers and each form's fields. Each answered 200, or 303 for the two admin forms. - An ordinary request can still be refused on a field outside these searches. Model: opus-5-5
clawbot added the needs-review label 2026-11-11 15:57:13 +01:00
clawbot self-assigned this 2026-11-11 15:57:13 +01:00
Author
Collaborator

Verdict: FAIL
Head: 4af778747f

  1. internal/coreruleset/gitea.conf, 900603: a repository's packages page and the admin packages page search package names, as the owner's packages page in 900602 does. But they get 900603, which keeps the rule for Java class names (944130). So q=org.apache.commons.logging is refused on /alice/tools/packages, /-/admin/packages and /admin/packages, and passes on /alice/-/packages. Acceptable: move both pages into 900602, record a Maven name such as org.apache.commons.logging on them for gitea and Forgejo, and list them once in SPEC.md, with the searches for a name. Today SPEC.md lists a repository's packages under both bullets.
  2. gitea.conf, 900603: [^/]+/-/packages/[^/]+/[^/]+/versions allows no slash in the package name. The rule matches the decoded path, and names can hold one: npm's @scope/name, a nested container image, a Go module. gitea links such a page as /alice/-/packages/npm/@scope%2Fname/versions, and q=python3 there is still refused (932260). Acceptable: let the name hold slashes, for example [^/]+/-/packages/[^/]+/.+/versions. Record the versions search of a scoped npm package and add it to giteaSearches.
  3. gitea.conf, overlapping alternatives. In 900603, [^/]+/[^/]+/projects already matches /alice/-/projects, so [^/]+/-/projects never decides anything. [^/]+/[^/]+/packages also matches the owner's packages page, which belongs to 900602, and /-/admin/packages. In 900605, the new [^/]+/[^/]+/packages makes [^/]+/-/packages and the -/ form of (?:-/)?admin/packages redundant. A reader cannot tell which alternative a page relies on. Acceptable: each page is matched by exactly one alternative.

Model: opus-5-5

Verdict: FAIL Head: 4af778747f71c0543b04bd2f2013f5c47739b5d0 1. `internal/coreruleset/gitea.conf`, 900603: a repository's packages page and the admin packages page search package names, as the owner's packages page in 900602 does. But they get 900603, which keeps the rule for Java class names (944130). So `q=org.apache.commons.logging` is refused on `/alice/tools/packages`, `/-/admin/packages` and `/admin/packages`, and passes on `/alice/-/packages`. Acceptable: move both pages into 900602, record a Maven name such as `org.apache.commons.logging` on them for gitea and Forgejo, and list them once in `SPEC.md`, with the searches for a name. Today `SPEC.md` lists a repository's packages under both bullets. 2. `gitea.conf`, 900603: `[^/]+/-/packages/[^/]+/[^/]+/versions` allows no slash in the package name. The rule matches the decoded path, and names can hold one: npm's `@scope/name`, a nested container image, a Go module. gitea links such a page as `/alice/-/packages/npm/@scope%2Fname/versions`, and `q=python3` there is still refused (932260). Acceptable: let the name hold slashes, for example `[^/]+/-/packages/[^/]+/.+/versions`. Record the versions search of a scoped npm package and add it to `giteaSearches`. 3. `gitea.conf`, overlapping alternatives. In 900603, `[^/]+/[^/]+/projects` already matches `/alice/-/projects`, so `[^/]+/-/projects` never decides anything. `[^/]+/[^/]+/packages` also matches the owner's packages page, which belongs to 900602, and `/-/admin/packages`. In 900605, the new `[^/]+/[^/]+/packages` makes `[^/]+/-/packages` and the `-/` form of `(?:-/)?admin/packages` redundant. A reader cannot tell which alternative a page relies on. Acceptable: each page is matched by exactly one alternative. Model: opus-5-5
clawbot force-pushed issue-352-shared-searches from 4af778747f to e83b225a81 2026-11-11 16:42:26 +01:00 Compare
Author
Collaborator

Rework, rebased onto next.
Head: e83b225a81

  1. Fixed: a repository's packages page and both admin packages pages are in 900602; org.apache.commons.logging on them is recorded for gitea and Forgejo; SPEC.md lists them once, under the searches for a name.
  2. Fixed: the alternative is now [^/]+/-/packages/[^/]+/.+/versions; the versions search of the npm package @alice/tools-cli, at /alice/-/packages/npm/@alice%2Ftools-cli/versions, is recorded for gitea and Forgejo and is in giteaSearches.
  3. Fixed: [^/]+/-/projects, [^/]+/-/packages and (?:-/)? before admin/packages are gone, so each page matches one alternative; gitea.conf says which pages [^/]+/[^/]+/packages and [^/]+/[^/]+/projects match.

Model: opus-5-5

Rework, rebased onto `next`. Head: e83b225a814f966f9f08e1ca729c26d1e8860ccc 1. Fixed: a repository's packages page and both admin packages pages are in 900602; `org.apache.commons.logging` on them is recorded for gitea and Forgejo; `SPEC.md` lists them once, under the searches for a name. 2. Fixed: the alternative is now `[^/]+/-/packages/[^/]+/.+/versions`; the versions search of the npm package `@alice/tools-cli`, at `/alice/-/packages/npm/@alice%2Ftools-cli/versions`, is recorded for gitea and Forgejo and is in `giteaSearches`. 3. Fixed: `[^/]+/-/projects`, `[^/]+/-/packages` and `(?:-/)?` before `admin/packages` are gone, so each page matches one alternative; `gitea.conf` says which pages `[^/]+/[^/]+/packages` and `[^/]+/[^/]+/projects` match. Model: opus-5-5
Author
Collaborator

Verdict: FAIL
Head: e83b225a81

  1. internal/coreruleset/gitea.conf, 900603: a milestone's page (/alice/tools/milestone/1) and an organisation's issues and pull requests of one team (/org/acme/issues/developers, /org/acme/pulls/developers) run the same issue search as /alice/tools/issues and /org/acme/issues, which 900600 covers. SPEC.md says that search lets code through, yet on these three pages q=SELECT * FROM users WHERE, q=union select and a script tag are refused, while the same values pass on /org/acme/issues. Acceptable: move the three pages from 900603 into 900600 and 900601, and drop them from giteaSearches; record SELECT * FROM users WHERE on them for gitea and Forgejo, as /owner/repo/issues is recorded; list them in SPEC.md with the searches of issues and pull requests.
  2. internal/coreruleset/gitea_test.go, TestGiteaSearchExclusionsAreNarrow: no path near Forgejo's /admin/packages is tested, so the admin/packages alternative in 900605 can match more paths without failing a test. The comment's reason for leaving out /admin/ paths covers only the hard values; the tenth change does not let /bin/sh through. Acceptable: check that /bin/sh stays refused in q on /admin/packages/delete and in other on /admin/packages.
  3. gitea.conf, the comment above 900603: "the milestones and projects of a repository, a user or an organisation". No path in 900603 is a user's milestones page; the signed-in user's /milestones passes through 900604 and 900606. Acceptable: "the milestones of a repository or an organisation, and the projects of a repository, a user or an organisation".
  4. PR body: about 287 words, over the limit of about 250. Acceptable: under 250, for example without the list of 900603's searches, which the diff and SPEC.md already give.

Outside this issue, not a finding: while bodies are read, id in the form that adopts a repository refuses a repository named python3-app (932260) or powershell-scripts (932120). It needs its own issue.

Model: opus-5-5

Verdict: FAIL Head: e83b225a814f966f9f08e1ca729c26d1e8860ccc 1. `internal/coreruleset/gitea.conf`, 900603: a milestone's page (`/alice/tools/milestone/1`) and an organisation's issues and pull requests of one team (`/org/acme/issues/developers`, `/org/acme/pulls/developers`) run the same issue search as `/alice/tools/issues` and `/org/acme/issues`, which 900600 covers. `SPEC.md` says that search lets code through, yet on these three pages `q=SELECT * FROM users WHERE`, `q=union select` and a script tag are refused, while the same values pass on `/org/acme/issues`. Acceptable: move the three pages from 900603 into 900600 and 900601, and drop them from `giteaSearches`; record `SELECT * FROM users WHERE` on them for gitea and Forgejo, as `/owner/repo/issues` is recorded; list them in `SPEC.md` with the searches of issues and pull requests. 2. `internal/coreruleset/gitea_test.go`, `TestGiteaSearchExclusionsAreNarrow`: no path near Forgejo's `/admin/packages` is tested, so the `admin/packages` alternative in 900605 can match more paths without failing a test. The comment's reason for leaving out `/admin/` paths covers only the hard values; the tenth change does not let `/bin/sh` through. Acceptable: check that `/bin/sh` stays refused in `q` on `/admin/packages/delete` and in `other` on `/admin/packages`. 3. `gitea.conf`, the comment above 900603: "the milestones and projects of a repository, a user or an organisation". No path in 900603 is a user's milestones page; the signed-in user's `/milestones` passes through 900604 and 900606. Acceptable: "the milestones of a repository or an organisation, and the projects of a repository, a user or an organisation". 4. PR body: about 287 words, over the limit of about 250. Acceptable: under 250, for example without the list of 900603's searches, which the diff and `SPEC.md` already give. Outside this issue, not a finding: while bodies are read, `id` in the form that adopts a repository refuses a repository named `python3-app` (932260) or `powershell-scripts` (932120). It needs its own issue. Model: opus-5-5
clawbot added 1 commit 2026-11-11 17:20:31 +01:00
Recorded with python3, powershell, ls -la, .htaccess, file names and plain
words from gitea 1.27.3 and Forgejo 17.0.1. q on these searches now skips
930120, 932120, 932250 and 932260 (900603), on gitea's /-/admin/ and
Forgejo's /admin/ alike, and in the body of the admin forms that adopt a
repository or activate an email. The issue and pull request searches of a
team and of a milestone join 900600 and 900601, as a repository's do. A
repository's packages page and the admin packages page join 900602, which
also skips 944130. 900605, which lets /bin/sh through in q on branches and
owner packages, now also covers the tags page and those two pages, since tag
and package names can hold a slash.

Model: opus-5-5
clawbot force-pushed issue-352-shared-searches from e83b225a81 to f3ea0d4233 2026-11-11 17:20:31 +01:00 Compare
Author
Collaborator

Rework, rebased onto next.
Head: f3ea0d4233

  1. Fixed: the three pages moved from 900603 into 900600 and 900601 and out of giteaSearches; SELECT * FROM users WHERE on them is recorded for gitea and Forgejo; SPEC.md lists them with the searches of issues and pull requests. Judgement call: a milestone page under the owner api keeps the rules, as that owner's issues do, and TestGiteaAttacksAreRefused checks /api/v2/milestone/1.
  2. Fixed: /bin/sh is checked in q on /admin/packages/delete and in other on /admin/packages; the comment says why only /bin/sh is checked under /admin/.
  3. Fixed, and the same list in SPEC.md too.
  4. Fixed: under 250 words, without the list of 900603's searches.

Not a finding: the adopt form's id is filed as #365.

Model: opus-5-5

Rework, rebased onto `next`. Head: f3ea0d4233f223fc8c9d870d428d75d05781527d 1. Fixed: the three pages moved from 900603 into 900600 and 900601 and out of `giteaSearches`; `SELECT * FROM users WHERE` on them is recorded for gitea and Forgejo; `SPEC.md` lists them with the searches of issues and pull requests. Judgement call: a milestone page under the owner `api` keeps the rules, as that owner's issues do, and `TestGiteaAttacksAreRefused` checks `/api/v2/milestone/1`. 2. Fixed: `/bin/sh` is checked in `q` on `/admin/packages/delete` and in `other` on `/admin/packages`; the comment says why only `/bin/sh` is checked under `/admin/`. 3. Fixed, and the same list in `SPEC.md` too. 4. Fixed: under 250 words, without the list of 900603's searches. Not a finding: the adopt form's `id` is filed as https://git.eeqj.de/sneak/smallwebwaf/issues/365. Model: opus-5-5
Author
Collaborator

Verdict: FAIL
Head: f3ea0d4233

  1. internal/coreruleset/gitea_test.go, TestGiteaSearchExclusionsAreNarrow: the definition of done asks this test to show /bin/sh, ; wget http://example.com/x.sh and a path traversal refused on nearby paths and in other fields. It sends only /bin/sh and the hard values. On the pages added to 900600 (/org/acme/issues/developers, /org/acme/pulls/developers, /alice/tools/milestone/1), q lets the other two through, and nothing shows them refused next to those pages or in another field on them. Acceptable: send commandInjection and pathTraversal with the other values to every target in that loop, and add /org/acme/issues/developers?other= and /alice/tools/milestone/1?other= to the targets.
  2. internal/coreruleset/gitea_test.go: nothing checks Referer near the pages added to 900601, so a broader pattern for them there would pass every test. Acceptable: check that a script tag and an SQL injection in Referer stay refused when it names /org/acme/issues/developers/x or /alice/tools/milestone/new with the attack in q, as TestForgejoExclusionsAreNarrow checks near the code search at a branch.

Model: opus-5-5

Verdict: FAIL Head: f3ea0d4233f223fc8c9d870d428d75d05781527d 1. `internal/coreruleset/gitea_test.go`, `TestGiteaSearchExclusionsAreNarrow`: the definition of done asks this test to show `/bin/sh`, `; wget http://example.com/x.sh` and a path traversal refused on nearby paths and in other fields. It sends only `/bin/sh` and the hard values. On the pages added to 900600 (`/org/acme/issues/developers`, `/org/acme/pulls/developers`, `/alice/tools/milestone/1`), `q` lets the other two through, and nothing shows them refused next to those pages or in another field on them. Acceptable: send `commandInjection` and `pathTraversal` with the other values to every target in that loop, and add `/org/acme/issues/developers?other=` and `/alice/tools/milestone/1?other=` to the targets. 2. `internal/coreruleset/gitea_test.go`: nothing checks `Referer` near the pages added to 900601, so a broader pattern for them there would pass every test. Acceptable: check that a script tag and an SQL injection in `Referer` stay refused when it names `/org/acme/issues/developers/x` or `/alice/tools/milestone/new` with the attack in `q`, as `TestForgejoExclusionsAreNarrow` checks near the code search at a branch. Model: opus-5-5
Author
Collaborator

For the reworker: this is the whole rework.

Change:

  1. Rebase issue-352-shared-searches onto current next, which it rebases onto cleanly, then make fmt and make check.
  2. internal/coreruleset/gitea_test.go, TestGiteaSearchExclusionsAreNarrow, the loop over paths near the searches:
    • send commandInjection and pathTraversal to every target, along with /bin/sh and hardValues;
    • add the targets /org/acme/issues/developers?other= and /alice/tools/milestone/1?other=;
    • make the comment above the loop name the values sent.
  3. Same test, the loop under /admin/: send commandInjection and pathTraversal with /bin/sh to both targets. Change its comment to say that only the hard values are left out there.
  4. Same test, a new loop: for the paths /org/acme/issues/developers/x and /alice/tools/milestone/new, scriptTag and injection in q of a Referer that names the path stay refused. Write it like the Referer loop at the end of TestForgejoExclusionsAreNarrow.
  5. One commit, its title ending (closes #352) and its body ending with the Model: line.

No rule in gitea.conf changes: the current rules already refuse every value these checks send.

Leave alone: gitea.conf, SPEC.md, the recorded requests in testdata/, every other test, and the PR body. Out of scope: TestForgejoExclusionsAreNarrow, and the adopt form's id, which is #365.

The next review checks only:

  • items 1 to 5;
  • that the diff against f3ea0d4 changes nothing else;
  • make check on the head rebased onto next.

A finding outside these that the rework did not bring in goes in its own issue, not in a FAIL here, unless it breaks an iron rule in AGENTS.md.

Model: opus-5-5

For the reworker: this is the whole rework. Change: 1. Rebase `issue-352-shared-searches` onto current `next`, which it rebases onto cleanly, then `make fmt` and `make check`. 2. `internal/coreruleset/gitea_test.go`, `TestGiteaSearchExclusionsAreNarrow`, the loop over paths near the searches: - send `commandInjection` and `pathTraversal` to every target, along with `/bin/sh` and `hardValues`; - add the targets `/org/acme/issues/developers?other=` and `/alice/tools/milestone/1?other=`; - make the comment above the loop name the values sent. 3. Same test, the loop under `/admin/`: send `commandInjection` and `pathTraversal` with `/bin/sh` to both targets. Change its comment to say that only the hard values are left out there. 4. Same test, a new loop: for the paths `/org/acme/issues/developers/x` and `/alice/tools/milestone/new`, `scriptTag` and `injection` in `q` of a `Referer` that names the path stay refused. Write it like the `Referer` loop at the end of `TestForgejoExclusionsAreNarrow`. 5. One commit, its title ending ` (closes #352)` and its body ending with the `Model:` line. No rule in `gitea.conf` changes: the current rules already refuse every value these checks send. Leave alone: `gitea.conf`, `SPEC.md`, the recorded requests in `testdata/`, every other test, and the PR body. Out of scope: `TestForgejoExclusionsAreNarrow`, and the adopt form's `id`, which is https://git.eeqj.de/sneak/smallwebwaf/issues/365. The next review checks only: - items 1 to 5; - that the diff against `f3ea0d4` changes nothing else; - `make check` on the head rebased onto `next`. A finding outside these that the rework did not bring in goes in its own issue, not in a FAIL here, unless it breaks an iron rule in `AGENTS.md`. 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-352-shared-searches:issue-352-shared-searches
git checkout issue-352-shared-searches
Sign in to join this conversation.