Gitea setup: the web attack rules refuse attacks and never ordinary Gitea traffic #198

Open
opened 2026-11-06 18:53:55 +01:00 by clawbot · 2 comments
Collaborator

sneak, in chat on 6 November, on hearing that the Gitea setup (#187) runs the web attack rules (the OWASP Core Rule Set) in detect-only mode, because at the defaults they refused ordinary Gitea searches and file names:

the web attack rules need to be changed if they flag ordinary gitea traffic as an attack. that’s a false positive.

Definition of done:

  • In the Gitea setup, the Core Rule Set refuses attacks (SWWAF_WAF_MODE is not detect).
  • Ordinary Gitea traffic is never refused:
    • code and issue searches with ordinary words and symbols;
    • viewing, downloading and editing files with any ordinary file name;
    • git clone, fetch and push over HTTPS;
    • API calls with JSON bodies;
    • the web pages a signed-in user opens.
  • Each rule that misfires on such a request is switched off as narrowly as it can be: that rule only, on the Gitea paths or fields where it misfires. A one-line comment names the Gitea request it misfired on. A misfire that would hit any site goes in smallwebwaf's default rules; one specific to Gitea goes in the Gitea setup.
  • A test sends a recorded set of ordinary Gitea requests through, and none is refused. The same test shows a few classic attacks still refused: SQL injection, path traversal, and script injection in a query string.
  • make check passes.

This builds on #187 once it lands.

Model: opus-5-5

sneak, in chat on 6 November, on hearing that the Gitea setup (https://git.eeqj.de/sneak/smallwebwaf/pulls/187) runs the web attack rules (the OWASP Core Rule Set) in detect-only mode, because at the defaults they refused ordinary Gitea searches and file names: > the web attack rules need to be changed if they flag ordinary gitea traffic as an attack. that’s a false positive. **Definition of done:** - In the Gitea setup, the Core Rule Set refuses attacks (`SWWAF_WAF_MODE` is not `detect`). - Ordinary Gitea traffic is never refused: - code and issue searches with ordinary words and symbols; - viewing, downloading and editing files with any ordinary file name; - git clone, fetch and push over HTTPS; - API calls with JSON bodies; - the web pages a signed-in user opens. - Each rule that misfires on such a request is switched off as narrowly as it can be: that rule only, on the Gitea paths or fields where it misfires. A one-line comment names the Gitea request it misfired on. A misfire that would hit any site goes in smallwebwaf's default rules; one specific to Gitea goes in the Gitea setup. - A test sends a recorded set of ordinary Gitea requests through, and none is refused. The same test shows a few classic attacks still refused: SQL injection, path traversal, and script injection in a query string. - `make check` passes. This builds on https://git.eeqj.de/sneak/smallwebwaf/pulls/187 once it lands. Model: opus-5-5
clawbot self-assigned this 2026-11-06 18:53:55 +01:00
Author
Collaborator

Plan for the implementer. Start from next once #187 has landed. docs/gitea.md, section "What the Core Rule Set refuses in block mode", lists every misfire found so far, with the rule ids; make gitea-requests reproduces them.

  • Misfires any site would hit (a query string that reads as an attack, a file or branch name that starts with a command name, a file name in a query parameter, a container layer reused): add a narrow exclusion to internal/waf's directives, beside smallwebwaf's existing changes to the Core Rule Set: SecRuleUpdateTargetById for that rule and that field, or a ctl exclusion limited to the path pattern. Each gets a one-line comment naming the request it misfired on. SPEC.md's "Attack detection" list of changes says what each one does.
  • Misfires only Gitea's own paths cause: a new servewaf setting, SWWAF_WAF_EXCLUSIONS_FILE, default empty: a file of Core Rule Set exclusions, in the same rule language, loaded after smallwebwaf's own directives. A file that cannot be read or does not parse fails startup. Rules in it may not use ids from 900000 to 900999. The Gitea setup ships deploy/gitea/crs-exclusions.conf, mounted read-only into servewaf, each exclusion limited to the Gitea path where it misfires, with its one-line comment. Package: internal/config parses the setting; internal/waf loads the file.
  • The setup: remove SWWAF_WAF_MODE: detect from deploy/gitea/compose.yaml, so it runs at the default, block.
  • The test: script/gitea-setup sends the ordinary requests script/gitea-requests sends (searches, file pages and downloads, edits, clone, fetch, push, API calls with JSON bodies, signed-in pages) and fails if any is refused. It also sends three attacks in a query string, SQL injection, path traversal and script injection, and fails unless each is refused.
  • Docs: docs/gitea.md's section on what the Core Rule Set refuses becomes a short section on the exclusions: where they live and how to add one. The README settings table and docs/settings.md list the new setting.
  • make check and make gitea-setup pass.

Disclosure for the PR body: the list of ordinary requests is what the test sends; a request outside it may still misfire, and goes in the exclusions file when found.

Model: opus-5-5

Plan for the implementer. Start from `next` once https://git.eeqj.de/sneak/smallwebwaf/pulls/187 has landed. `docs/gitea.md`, section "What the Core Rule Set refuses in `block` mode", lists every misfire found so far, with the rule ids; `make gitea-requests` reproduces them. - **Misfires any site would hit** (a query string that reads as an attack, a file or branch name that starts with a command name, a file name in a query parameter, a container layer reused): add a narrow exclusion to `internal/waf`'s directives, beside smallwebwaf's existing changes to the Core Rule Set: `SecRuleUpdateTargetById` for that rule and that field, or a `ctl` exclusion limited to the path pattern. Each gets a one-line comment naming the request it misfired on. `SPEC.md`'s "Attack detection" list of changes says what each one does. - **Misfires only Gitea's own paths cause:** a new servewaf setting, `SWWAF_WAF_EXCLUSIONS_FILE`, default empty: a file of Core Rule Set exclusions, in the same rule language, loaded after smallwebwaf's own directives. A file that cannot be read or does not parse fails startup. Rules in it may not use ids from 900000 to 900999. The Gitea setup ships `deploy/gitea/crs-exclusions.conf`, mounted read-only into `servewaf`, each exclusion limited to the Gitea path where it misfires, with its one-line comment. Package: `internal/config` parses the setting; `internal/waf` loads the file. - **The setup:** remove `SWWAF_WAF_MODE: detect` from `deploy/gitea/compose.yaml`, so it runs at the default, `block`. - **The test:** `script/gitea-setup` sends the ordinary requests `script/gitea-requests` sends (searches, file pages and downloads, edits, clone, fetch, push, API calls with JSON bodies, signed-in pages) and fails if any is refused. It also sends three attacks in a query string, SQL injection, path traversal and script injection, and fails unless each is refused. - **Docs:** `docs/gitea.md`'s section on what the Core Rule Set refuses becomes a short section on the exclusions: where they live and how to add one. The README settings table and `docs/settings.md` list the new setting. - `make check` and `make gitea-setup` pass. Disclosure for the PR body: the list of ordinary requests is what the test sends; a request outside it may still misfire, and goes in the exclusions file when found. Model: opus-5-5
Author
Collaborator

Correction to the plan above, from the naming audit (#192 (comment)): the new setting is SWWAF_CORE_RULE_SET_EXCLUSIONS_FILE, not SWWAF_WAF_EXCLUSIONS_FILE. The other SWWAF_WAF_ settings keep their names in this unit; the audit's rename unit changes them later. Everything else in the plan stands.

Model: opus-5-5

Correction to the plan above, from the naming audit (https://git.eeqj.de/sneak/smallwebwaf/issues/192#issuecomment-169850): the new setting is `SWWAF_CORE_RULE_SET_EXCLUSIONS_FILE`, not `SWWAF_WAF_EXCLUSIONS_FILE`. The other `SWWAF_WAF_` settings keep their names in this unit; the audit's rename unit changes them later. Everything else in the plan stands. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/smallwebwaf#198