SPEC: gitea cookies and Referer kept from false refusals (closes #6)
Seventh review of the spec update: - The Core Rule Set now reads requests without the `gitea_flash` and `redirect_to` cookies. A refusal there kept a browser out of the whole site, and not only 930120, 932160 and 932260 refuse ordinary names in them: the Java, script, PowerShell and database-name rules do too. Risks names an app that reads either cookie. - `Referer` is left out of 932340 and 944110, which refused every request made from the results of a one-word search such as `env`, and from OpenJDK's `java.base` pages that name `Runtime`. - The search note covers text whose first word has a listed command right after a `/`. Model: opus-5-5
This commit is contained in:
@@ -538,7 +538,7 @@ 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, since in
|
||||
- The sidecar also changes the Core Rule Set 4.25.0 in six 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
|
||||
@@ -559,25 +559,50 @@ The settings, by group:
|
||||
- The query parameters in which gitea sends file paths, branch and
|
||||
workflow names and the page to return to after signing in (`path`,
|
||||
`files`, `skip-to`, `sub_path`, `ref`, `sha`, `branch`, `workflow`,
|
||||
`artifactName` and `redirect_to`), and the `redirect_to` cookie, are
|
||||
not checked against the Core Rule Set's lists of system files
|
||||
(930120), shell paths (932160) and command names (932260). In a
|
||||
repository any name on those lists can be an ordinary file or branch,
|
||||
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. 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").
|
||||
`artifactName` and `redirect_to`) are not checked against the Core
|
||||
Rule Set's lists of system files (930120), shell paths (932160) and
|
||||
command names (932260). In a repository any name on those lists can be
|
||||
an ordinary file or branch, 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. 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 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").
|
||||
- The Core Rule Set reads the request without the `gitea_flash` and
|
||||
`redirect_to` cookies, and does not check `Referer` for a Unix command
|
||||
given without arguments (932340) or for Java starting a process
|
||||
(944110). Gitea writes into `gitea_flash` a message for the next page
|
||||
naming what was just done, such as a file deleted in the web editor or
|
||||
a branch, milestone or project created, and into `redirect_to` the
|
||||
page to return to after signing in, often the one the visitor clicked
|
||||
"Sign in" on; `Referer` is the address of the page a request comes
|
||||
from. In these cookies the Core Rule Set takes names such as
|
||||
`package.json`, `document.write.js` or `Get-ChildItem.ps1`, and titles
|
||||
that hold them, for attacks. In `Referer` it takes the address of a
|
||||
search for one word, such as `env`, `set` or `last`, when the address
|
||||
ends in it, and the address of OpenJDK's
|
||||
`src/java.base/share/classes/java/lang/Runtime.java`, which holds both
|
||||
`runtime` and `java.`. A browser sends such a cookie with every
|
||||
request until gitea replaces or removes it, which gitea cannot do
|
||||
while the sidecar refuses those requests, so one refusal would keep
|
||||
the browser out of the whole site. A browser names a page in `Referer`
|
||||
on everything the page loads and on every link followed from it, so
|
||||
all of those would be refused. Gitea shows the message with any script
|
||||
removed and returns only to a page of its own site. Like the other
|
||||
changes, this one holds in front of every app: an attack sent in a
|
||||
cookie of either name is not refused by the Core Rule Set, nor is a
|
||||
Unix command without arguments or Java starting a process sent in
|
||||
`Referer`. Every other cookie is read in full, and `Referer` keeps the
|
||||
other rules, script and SQL injection among them.
|
||||
- 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.
|
||||
@@ -1153,7 +1178,9 @@ networks:
|
||||
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.
|
||||
is read, and the page gitea shows after a change with its message naming
|
||||
what was done, such as a file deleted or a branch, milestone or project
|
||||
created.
|
||||
- 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
|
||||
@@ -1162,7 +1189,8 @@ networks:
|
||||
- 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
|
||||
starts with a command name, or whose first word has one right after a
|
||||
`/`, such as `python3`, `ssh key` or `feat/docker-support`; 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
|
||||
@@ -1289,7 +1317,9 @@ networks:
|
||||
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.
|
||||
them with a rule file. So does an app that reads a cookie named `gitea_flash`
|
||||
or `redirect_to`, which the Core Rule Set does not read, or passes `Referer`
|
||||
to a shell.
|
||||
- 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