SPEC.md "Rule files" defines the path target as the URL path as received, before any decoding, and every probe rule in the default file (and in the 50-gitea.rules example) uses path. So a client sending /%2eenv is not matched by env-file, while an app that decodes the path, as Go's server does, serves /.env. Found in review of #83, which builds the spec as written.
Options:
path is matched both as received and once percent-decoded, as uri already is. No new target; a rule written for the sent form still matches it.
The default file's probe rules use uri instead of path. uri holds the query too, so each regex ending in $ must also allow a query after the path.
Leave it; the Core Rule Set, a later stage, catches some encoded probes.
Recommendation: 1. Whichever you pick lands as its own change after #83; nothing waits on it.
Model: opus-5-5
`SPEC.md` "Rule files" defines the `path` target as the URL path as received, before any decoding, and every probe rule in the default file (and in the `50-gitea.rules` example) uses `path`. So a client sending `/%2eenv` is not matched by `env-file`, while an app that decodes the path, as Go's server does, serves `/.env`. Found in review of https://git.eeqj.de/sneak/smallwebwaf/pulls/83, which builds the spec as written.
Options:
1. `path` is matched both as received and once percent-decoded, as `uri` already is. No new target; a rule written for the sent form still matches it.
2. The default file's probe rules use `uri` instead of `path`. `uri` holds the query too, so each regex ending in `$` must also allow a query after the path.
3. Leave it; the Core Rule Set, a later stage, catches some encoded probes.
Recommendation: 1. Whichever you pick lands as its own change after https://git.eeqj.de/sneak/smallwebwaf/pulls/83; nothing waits on it.
Model: opus-5-5
sneak
was assigned by clawbot2026-10-06 18:16:27 +02:00
Settled by the standing rulings, so it no longer waits on sneak: building option 1. It is small and easy to undo, neither other option matters more, and SPEC.md already says why uri is matched once decoded: "so an encoded probe cannot slip past". The path target should do the same.
What to do (one PR to next)
A path rule matches if its regex matches the path as sent (rules.Path) or that path decoded once (decodeOnce, as uri does). Decode after cutting off the query, so a %3F cannot move the split. Decode once only: /%252eenv is not /.env.
SWWAF_TRAP_PATHS is matched against "the path a path rule sees", so it follows: a trap path matches the path as sent or decoded once. /%77p-login.php now matches /wp-login.php. The ban's notes keep the path as sent. This is a judgement call, disclosed here: the README's example says the opposite and is changed with it.
SPEC.md "Rule files" (path target) and the README's rule file and trap path text say the new behaviour. Change only the sentences this affects.
Tests: /%2eenv is caught by the default env-file rule; /%77p-login.php is caught as a trap path; /%252eenv and a broken escape such as /%zz.env behave as the brief says. Each new test must fail with the change taken out.
Definition of done: make check passes, and a reviewer who did not write the PR passes it.
Model: opus-5-5
Settled by the standing rulings, so it no longer waits on sneak: building option 1. It is small and easy to undo, neither other option matters more, and `SPEC.md` already says why `uri` is matched once decoded: "so an encoded probe cannot slip past". The `path` target should do the same.
## What to do (one PR to `next`)
- A `path` rule matches if its regex matches the path as sent (`rules.Path`) or that path decoded once (`decodeOnce`, as `uri` does). Decode after cutting off the query, so a `%3F` cannot move the split. Decode once only: `/%252eenv` is not `/.env`.
- `SWWAF_TRAP_PATHS` is matched against "the path a `path` rule sees", so it follows: a trap path matches the path as sent or decoded once. `/%77p-login.php` now matches `/wp-login.php`. The ban's notes keep the path as sent. This is a judgement call, disclosed here: the README's example says the opposite and is changed with it.
- `SPEC.md` "Rule files" (`path` target) and the README's rule file and trap path text say the new behaviour. Change only the sentences this affects.
- Tests: `/%2eenv` is caught by the default `env-file` rule; `/%77p-login.php` is caught as a trap path; `/%252eenv` and a broken escape such as `/%zz.env` behave as the brief says. Each new test must fail with the change taken out.
Definition of done: `make check` passes, and a reviewer who did not write the PR passes it.
Model: opus-5-5
sneak
was unassigned by clawbot2026-10-14 17:26:24 +02:00
clawbot
self-assigned this 2026-10-14 17:26:24 +02:00
Built in #125, as the brief above says. A path rule and a path in SWWAF_TRAP_PATHS now match the path as sent or decoded once, and the ban's notes keep the path as sent. SPEC.md and the README say so.
One thing the brief could not get: a malformed escape such as /%zz.env never reaches a path rule, because Go's HTTP server answers it 400 itself. There is no test for it.
Model: opus-5-5
Built in https://git.eeqj.de/sneak/smallwebwaf/pulls/125, as the brief above says. A `path` rule and a path in `SWWAF_TRAP_PATHS` now match the path as sent or decoded once, and the ban's notes keep the path as sent. `SPEC.md` and the README say so.
One thing the brief could not get: a malformed escape such as `/%zz.env` never reaches a path rule, because Go's HTTP server answers it `400` itself. There is no test for it.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
SPEC.md"Rule files" defines thepathtarget as the URL path as received, before any decoding, and every probe rule in the default file (and in the50-gitea.rulesexample) usespath. So a client sending/%2eenvis not matched byenv-file, while an app that decodes the path, as Go's server does, serves/.env. Found in review of #83, which builds the spec as written.Options:
pathis matched both as received and once percent-decoded, asurialready is. No new target; a rule written for the sent form still matches it.uriinstead ofpath.uriholds the query too, so each regex ending in$must also allow a query after the path.Recommendation: 1. Whichever you pick lands as its own change after #83; nothing waits on it.
Model: opus-5-5
clawbot referenced this issue2026-10-06 20:38:53 +02:00
Settled by the standing rulings, so it no longer waits on sneak: building option 1. It is small and easy to undo, neither other option matters more, and
SPEC.mdalready says whyuriis matched once decoded: "so an encoded probe cannot slip past". Thepathtarget should do the same.What to do (one PR to
next)pathrule matches if its regex matches the path as sent (rules.Path) or that path decoded once (decodeOnce, asuridoes). Decode after cutting off the query, so a%3Fcannot move the split. Decode once only:/%252eenvis not/.env.SWWAF_TRAP_PATHSis matched against "the path apathrule sees", so it follows: a trap path matches the path as sent or decoded once./%77p-login.phpnow matches/wp-login.php. The ban's notes keep the path as sent. This is a judgement call, disclosed here: the README's example says the opposite and is changed with it.SPEC.md"Rule files" (pathtarget) and the README's rule file and trap path text say the new behaviour. Change only the sentences this affects./%2eenvis caught by the defaultenv-filerule;/%77p-login.phpis caught as a trap path;/%252eenvand a broken escape such as/%zz.envbehave as the brief says. Each new test must fail with the change taken out.Definition of done:
make checkpasses, and a reviewer who did not write the PR passes it.Model: opus-5-5
Built in #125, as the brief above says. A
pathrule and a path inSWWAF_TRAP_PATHSnow match the path as sent or decoded once, and the ban's notes keep the path as sent.SPEC.mdand the README say so.One thing the brief could not get: a malformed escape such as
/%zz.envnever reaches a path rule, because Go's HTTP server answers it400itself. There is no test for it.Model: opus-5-5