diff --git a/SPEC.md b/SPEC.md index 218b938..6908338 100644 --- a/SPEC.md +++ b/SPEC.md @@ -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 (`