SPEC: parameter change for every app, gitea name refusals, v3 uploads (closes #6)
Fifth review of the spec update: - The change that leaves gitea's path and branch parameters out of 930120, 932160 and 932260 says it holds in front of every app, that commands and file URLs pass there too, and that no setting restores the rules; Risks names an app that uses one of them as a server file or in a shell. - The gitea notes no longer claim that any branch or file name passes: they name `refSubUrl`, `name`, `tag`, `template` and `rule_name`, which keep the rules, and what each refusal looks like. - `actions/upload-artifact@v3` is refused once or twice per upload and the step fails; only more than 30 refusals a minute ban the runner. Model: opus-5-5
This commit is contained in:
@@ -538,9 +538,9 @@ The settings, by group:
|
||||
- `WAF_PARANOIA_LEVEL` (default `1`), `WAF_ANOMALY_THRESHOLD` (default `5`):
|
||||
the Core Rule Set's own two tuning values, at the Core Rule Set's own
|
||||
defaults.
|
||||
- The sidecar also changes the Core Rule Set 4.25.0 in five ways that no
|
||||
setting undoes, since in front of gitea each would otherwise refuse
|
||||
ordinary requests:
|
||||
- The sidecar also changes the Core Rule Set 4.25.0 in five 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:
|
||||
- PUT, PATCH and DELETE are allowed methods besides GET, HEAD, POST and
|
||||
OPTIONS; APIs, container image pushes and package uploads use them.
|
||||
Other methods stay refused.
|
||||
@@ -566,11 +566,18 @@ The settings, by group:
|
||||
such as `.gitignore`, `package.json`, `docker-compose.yml`,
|
||||
`bin/docker-entrypoint` or a branch named `docker-build`, and gitea
|
||||
reads these values as names within a repository or its own records, or
|
||||
as a page of its own site. What only these three rules refuse, such as
|
||||
`/etc/passwd` or `whoami` on its own, is therefore let through in
|
||||
those parameters; path traversal (`../`), SQL and script injection and
|
||||
PHP, Java and Node.js code are still refused there, and every other
|
||||
parameter and cookie keeps all three rules.
|
||||
as a page of its own site. Like the other changes, this one holds in
|
||||
front of every app, not only gitea, and no setting restores the three
|
||||
rules in those parameters. What only these three rules refuse is let
|
||||
through there, and that is more than a name such as `/etc/passwd` or
|
||||
`whoami` on its own: commands such as `|cat /etc/passwd`,
|
||||
`wget http://…` and `nc -e /bin/sh …`, and `file:///etc/passwd`, pass
|
||||
as well. Path traversal (`../`), SQL and script injection and PHP,
|
||||
Java and Node.js code are still refused there, and every other
|
||||
parameter and cookie keeps all three rules. An app that uses one of
|
||||
these parameters as a file on the server, or passes it to a shell,
|
||||
gets no help from the three rules there (see "Risks the design has to
|
||||
handle").
|
||||
- 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.
|
||||
@@ -1136,36 +1143,59 @@ networks:
|
||||
`UPSTREAM_REQUEST_TIMEOUT` raised to fit. The Core Rule Set does not read
|
||||
an upload's body, which streams through without being held in memory.
|
||||
- At the defaults (see "Configuration surface", attack detection), the Core
|
||||
Rule Set lets gitea's ordinary use through, whatever its files and
|
||||
branches are called: browsing and views of files in a repository, with
|
||||
their history, blame and the file tree; diffs, including their hidden
|
||||
lines and large files, and pull request review; git's clone, fetch and
|
||||
push over HTTP; signing in, including the return to the page a visitor
|
||||
came from and sign-in with Git Credential Manager, git-credential-oauth or
|
||||
tea; the API's calls for a file and its commits; pushing and pulling
|
||||
container images and packages; Actions runners, and artifacts uploaded
|
||||
with `actions/upload-artifact@v4`; and posting issues, pull requests,
|
||||
comments, wiki pages and files saved in the web editor, code included,
|
||||
since no body is read. It can still refuse a query string that reads to it
|
||||
as an attack, most often a search: one for a name on its lists of system
|
||||
files and commands, such as `package.json`, `.gitignore` or
|
||||
`docker-compose.yml`, or for text that starts with a command name, such as
|
||||
`python3` or `ssh key`; or one holding a shell command with its options or
|
||||
a system path (`ls -la`, `sed -i`, `/bin/sh`), a command in backticks,
|
||||
script code (`fetch(`, `${VAR}`, `process.env`), HTML (`<img src=`), an
|
||||
SQL statement (`SELECT * FROM users WHERE`), or a URL naming an IP address
|
||||
or `localhost`. The lists refuse such a name in any other query parameter
|
||||
Rule Set lets gitea's ordinary use through, apart from the refusals in the
|
||||
next note: browsing and views of files in a repository, with their
|
||||
history, blame and the file tree; diffs, including their hidden lines and
|
||||
large files, and pull request review; git's clone, fetch and push over
|
||||
HTTP; signing in, including the return to the page a visitor came from and
|
||||
sign-in with Git Credential Manager, git-credential-oauth or tea; the
|
||||
API's calls for a file and its commits; pushing and pulling container
|
||||
images and packages; Actions runners, and artifacts uploaded with
|
||||
`actions/upload-artifact@v4`; and posting issues, pull requests, comments,
|
||||
wiki pages and files saved in the web editor, code included, since no body
|
||||
is read.
|
||||
- The Core Rule Set can still refuse the requests below. Each refusal
|
||||
answers only that request, with 403, and bans no one by itself: it counts
|
||||
toward the error burst, which a person does not reach this way. The
|
||||
request log names the rule in `waf_rule_ids`, which `WAF_DISABLED_RULES`
|
||||
can switch off.
|
||||
- A query string that reads to it as an attack, most often a search: one
|
||||
for a name on its lists of system files and commands, such as
|
||||
`package.json`, `.gitignore` or `docker-compose.yml`, or for text that
|
||||
starts with a command name, such as `python3` or `ssh key`; or one
|
||||
holding a shell command with its options or a system path (`ls -la`,
|
||||
`sed -i`, `/bin/sh`), a command in backticks, script code (`fetch(`,
|
||||
`${VAR}`, `process.env`), HTML (`<img src=`), an SQL statement
|
||||
(`SELECT * FROM users WHERE`), or a URL naming an IP address or
|
||||
`localhost`. The lists refuse such a name in any other query parameter
|
||||
too, such as a release attachment uploaded through the API as
|
||||
`docker-compose.yml`. A path can be refused as well: a file name ending in
|
||||
`~`, or an `.xhtml` file whose path holds a space. Such a refusal answers
|
||||
only that request, with 403, and bans no one by itself: it counts toward
|
||||
the error burst, which a person searching does not reach. The request log
|
||||
names the rule in `waf_rule_ids`, which `WAF_DISABLED_RULES` can switch
|
||||
off.
|
||||
`docker-compose.yml`.
|
||||
- A branch, tag or file name that starts with `docker-`, `python3`,
|
||||
`ansible`, `base64`, `whoami` or another entry on the Core Rule Set's
|
||||
list of commands (932260), where gitea's own pages send it in a query
|
||||
parameter that 930120, 932160 and 932260 still check: `refSubUrl`, the
|
||||
branch or tag of a directory listing, sent when the listing asks for
|
||||
its entries' last commits in a second request, as it does whenever
|
||||
gitea takes more than a second to work them out; `name`, when a branch
|
||||
is deleted or restored on the branches page; `tag`, when a release is
|
||||
started from a tag; `template`, the file of an issue template, when an
|
||||
issue is opened from it; and `rule_name`, when a branch protection
|
||||
rule is opened for editing in the repository's settings. For a branch
|
||||
named `docker-build`, a directory listing that makes that second
|
||||
request leaves those last commits out and shows an error, and the
|
||||
branches page shows an error instead of deleting or restoring the
|
||||
branch. A release started from such a tag, an issue from such a
|
||||
template or such a rule opened for editing gets the sidecar's 403
|
||||
answer in place of its form.
|
||||
- A path: a file name ending in `~`, or an `.xhtml` file whose path
|
||||
holds a space.
|
||||
- Artifact uploads from `actions/upload-artifact@v3` send the header
|
||||
`Content-Range`, which the Core Rule Set refuses (920450). Each file of
|
||||
the artifact is refused with 403 and the step fails; an artifact of more
|
||||
than 30 files also bans the runner through the error burst.
|
||||
`Content-Range`, which the Core Rule Set refuses (920450). The action
|
||||
sends two files at a time, does not retry a 403 and sends no further file
|
||||
once one is refused, so an upload is refused once or twice, however many
|
||||
files it holds, and the step fails. One upload does not ban the runner;
|
||||
more than 30 such refusals from its address within a minute, as when many
|
||||
jobs upload at once, ban it through the error burst.
|
||||
`actions/upload-artifact@v4` does not send the header.
|
||||
- An Actions runner that reaches gitea through the sidecar sends requests
|
||||
all day. One older than version 0.4 (April 2026) asks for work every 2
|
||||
@@ -1248,6 +1278,14 @@ networks:
|
||||
attack is still subject to the rule files, the limits and the bans, and
|
||||
`WAF_BODY_LIMIT` switches body inspection on for apps whose forms carry no
|
||||
code.
|
||||
- An app that uses `path`, `ref` or another of the query parameters left out of
|
||||
930120, 932160 and 932260 (see "Configuration surface", attack detection) as a
|
||||
file on the server, or passes it to a shell: that change holds in front of
|
||||
every app and no setting restores the three rules, so what only they refuse
|
||||
reaches the app in those parameters, such as `/etc/passwd`, `|cat /etc/passwd`
|
||||
or `nc -e /bin/sh …`. Path traversal (`../`) is still refused there. Such an
|
||||
app has to check those values itself, or refuse what it must never receive in
|
||||
them with a rule file.
|
||||
- The admin endpoints can be reached from the internet: all but the health check
|
||||
need a token and are off while it is unset, and a missing or wrong token
|
||||
counts toward the error burst, so a client guessing tokens is soon banned.
|
||||
|
||||
Reference in New Issue
Block a user