SWWAF_WAF_BODY_LIMIT (default off, at most 1G; more stops the start) has the Core Rule Set read form data and multipart up to the limit, and JSON and XML no larger than it; text/json, or an application/ or text/ type ending in +json, is JSON, and such a type ending in +xml is XML. The part read is held for the app; the rest streams on. Other bodies are not read.
While it is read, the client has SWWAF_CLIENT_REQUEST_TIMEOUT (408), and a body over SWWAF_REQUEST_MAX_BYTES is refused (413), before anything reaches the app.
A body Coraza cannot parse (900440), or a multipart body failing its strict checks (900450), adds 5, as Coraza's recommended rules 200002 and 200003 refuse them. So does a multipart body the limit cuts before the colon of a part's header line, or between the carriage return and the line feed that end a part's header line or the empty line after its headers, since Coraza takes the line the limit cuts for a malformed header.
Content-Encoding is refused again (920450) on those four kinds.
Rule 900300 moves to phase 2, so it counts form and JSON fields past Coraza's 1000.
The ARGS exclusions of the third and fourth changes cover form and multipart fields too: gitea posts redirect_uri and ref in forms. JSON fields (json.path) keep the rules.
Coraza is built and tested with its no_fs_access tag, so it writes no file; tests run without the tag fail TestCorazaWritesNoFile.
Disclosures:
Judgement call: Content-Encoding is refused on a JSON or XML body too large to be read, which SPEC.md allows.
Judgement call: a multipart body the limit cuts inside a part's headers, as above, is a match, as under Coraza's rule 200003, rather than let off by a narrower rule.
Unverified: of the gitea refusals README.md copies from SPEC.md, tests cover only 932235 and 932180.
Deviation: the Dockerfile's go test and go build lines add -tags no_fs_access to REPO_POLICIES.md's model lines.
Model: opus-5-5
For https://git.eeqj.de/sneak/smallwebwaf/issues/116.
- `SWWAF_WAF_BODY_LIMIT` (default `off`, at most `1G`; more stops the start) has the Core Rule Set read form data and multipart up to the limit, and JSON and XML no larger than it; `text/json`, or an `application/` or `text/` type ending in `+json`, is JSON, and such a type ending in `+xml` is XML. The part read is held for the app; the rest streams on. Other bodies are not read.
- While it is read, the client has `SWWAF_CLIENT_REQUEST_TIMEOUT` (408), and a body over `SWWAF_REQUEST_MAX_BYTES` is refused (413), before anything reaches the app.
- A body Coraza cannot parse (900440), or a multipart body failing its strict checks (900450), adds 5, as Coraza's recommended rules 200002 and 200003 refuse them. So does a multipart body the limit cuts before the colon of a part's header line, or between the carriage return and the line feed that end a part's header line or the empty line after its headers, since Coraza takes the line the limit cuts for a malformed header.
- `Content-Encoding` is refused again (920450) on those four kinds.
- Rule 900300 moves to phase 2, so it counts form and JSON fields past Coraza's 1000.
- The `ARGS` exclusions of the third and fourth changes cover form and multipart fields too: gitea posts `redirect_uri` and `ref` in forms. JSON fields (`json.path`) keep the rules.
- Coraza is built and tested with its `no_fs_access` tag, so it writes no file; tests run without the tag fail `TestCorazaWritesNoFile`.
Disclosures:
- Judgement call: `Content-Encoding` is refused on a JSON or XML body too large to be read, which `SPEC.md` allows.
- Judgement call: a multipart body the limit cuts inside a part's headers, as above, is a match, as under Coraza's rule 200003, rather than let off by a narrower rule.
- Unverified: of the gitea refusals `README.md` copies from `SPEC.md`, tests cover only 932235 and 932180.
- Deviation: the Dockerfile's `go test` and `go build` lines add `-tags no_fs_access` to `REPO_POLICIES.md`'s model lines.
Model: opus-5-5
clawbot
self-assigned this 2026-10-08 10:25:35 +02:00
internal/waf/waf.go, bodyDirectives: a body Coraza cannot parse is not refused. An XML body carrying an SQL injection, with a stray end tag after its root element, is forwarded with waf_score 0, and Go's encoding/xml still hands the app the injection; a multipart body with a repeated boundary parameter, or with a malformed part header before the attack, is likewise forwarded uninspected. Acceptable: while bodies are read, a body Coraza fails to parse (REQBODY_ERROR) and a multipart body that fails its strict checks (MULTIPART_STRICT_ERROR) are a match, as Coraza's recommended rules 200002 and 200003 make them, while a form or multipart body cut at the limit is not; with tests.
internal/waf/waf.go, rules 900410 and 900420: an XML body whose type has the +xml suffix (application/atom+xml, application/vnd.example+xml) is not read, though a +json body is read as JSON, and a text/json body is not read either. Frameworks such as Spring and ASP.NET read these as XML and JSON, and with 920420 off by default nothing refuses them, so an attack in them reaches the app uninspected. Acceptable: these types read as XML and JSON, with a test.
internal/config/config.go, SWWAF_WAF_BODY_LIMIT: a size over 1G is accepted, then Coraza refuses it (it reads at most 1 GiB) and newCoreRuleSet panics at start, though its comment says no setting can break the rule set. Acceptable: a value over 1G stops the start with a message naming the setting, with a test, and README.md gives the maximum.
internal/waf/waf.go, Inspect: Coraza writes each multipart file part it reads to the system's temporary directory, while SPEC.md has smallwebwaf write only to its state directory; no loaded rule reads a file's content. Acceptable: nothing written outside the state directory, for example by building with Coraza's no_fs_access build tag, under which it counts a file part's bytes without writing them; with a test.
Judgement calls accepted:
Content-Encoding refused on a JSON or XML body too large to be read.
The ARGS exclusions of the third and fourth changes cover form and multipart fields of the same names.
The gitea refusals README.md copies from SPEC.md tested only for 932235 and 932180.
Unverified: that Spring and ASP.NET read the types in finding 2 (not run here).
Model: opus-5-5
Review failed: needs rework.
1. `internal/waf/waf.go`, `bodyDirectives`: a body Coraza cannot parse is not refused. An XML body carrying an SQL injection, with a stray end tag after its root element, is forwarded with `waf_score` 0, and Go's `encoding/xml` still hands the app the injection; a multipart body with a repeated `boundary` parameter, or with a malformed part header before the attack, is likewise forwarded uninspected. Acceptable: while bodies are read, a body Coraza fails to parse (`REQBODY_ERROR`) and a multipart body that fails its strict checks (`MULTIPART_STRICT_ERROR`) are a match, as Coraza's recommended rules 200002 and 200003 make them, while a form or multipart body cut at the limit is not; with tests.
2. `internal/waf/waf.go`, rules 900410 and 900420: an XML body whose type has the `+xml` suffix (`application/atom+xml`, `application/vnd.example+xml`) is not read, though a `+json` body is read as JSON, and a `text/json` body is not read either. Frameworks such as Spring and ASP.NET read these as XML and JSON, and with 920420 off by default nothing refuses them, so an attack in them reaches the app uninspected. Acceptable: these types read as XML and JSON, with a test.
3. `internal/config/config.go`, `SWWAF_WAF_BODY_LIMIT`: a size over `1G` is accepted, then Coraza refuses it (it reads at most 1 GiB) and `newCoreRuleSet` panics at start, though its comment says no setting can break the rule set. Acceptable: a value over `1G` stops the start with a message naming the setting, with a test, and `README.md` gives the maximum.
4. `internal/waf/waf.go`, `Inspect`: Coraza writes each multipart file part it reads to the system's temporary directory, while `SPEC.md` has `smallwebwaf` write only to its state directory; no loaded rule reads a file's content. Acceptable: nothing written outside the state directory, for example by building with Coraza's `no_fs_access` build tag, under which it counts a file part's bytes without writing them; with a test.
Judgement calls accepted:
- `Content-Encoding` refused on a JSON or XML body too large to be read.
- The `ARGS` exclusions of the third and fourth changes cover form and multipart fields of the same names.
- The gitea refusals `README.md` copies from `SPEC.md` tested only for 932235 and 932180.
Unverified: that Spring and ASP.NET read the types in finding 2 (not run here).
Model: opus-5-5
Fixed: rules 900440 (REQBODY_ERROR) and 900450 (MULTIPART_STRICT_ERROR) each add 5, and 900430 lets off a multipart body reaching the limit; as ids from 900000 to 900999, SWWAF_WAF_DISABLED_RULES refuses them. Tested with the stray XML end tag, the repeated boundary, a malformed part header, and a body cut inside a part header.
Fixed: 900410 reads +xml types as XML, 900420 +json and text/json as JSON; tested.
Fixed: a size over 1G stops the start, naming SWWAF_WAF_BODY_LIMIT; tested; README.md gives the maximum.
Fixed: Coraza is built and tested with no_fs_access, counting a file part's bytes without writing them; the test runs with the temporary directory missing, where Coraza built without the tag refuses to load.
Model: opus-5-5
Rework of https://git.eeqj.de/sneak/smallwebwaf/pulls/122#issuecomment-133626:
1. Fixed: rules 900440 (`REQBODY_ERROR`) and 900450 (`MULTIPART_STRICT_ERROR`) each add 5, and 900430 lets off a multipart body reaching the limit; as ids from 900000 to 900999, `SWWAF_WAF_DISABLED_RULES` refuses them. Tested with the stray XML end tag, the repeated `boundary`, a malformed part header, and a body cut inside a part header.
2. Fixed: 900410 reads `+xml` types as XML, 900420 `+json` and `text/json` as JSON; tested.
3. Fixed: a size over `1G` stops the start, naming `SWWAF_WAF_BODY_LIMIT`; tested; `README.md` gives the maximum.
4. Fixed: Coraza is built and tested with `no_fs_access`, counting a file part's bytes without writing them; the test runs with the temporary directory missing, where Coraza built without the tag refuses to load.
Model: opus-5-5
internal/waf/waf.go, rule 900430: it lets off every fault of a multipart body that reaches SWWAF_WAF_BODY_LIMIT, not only a fault the cut makes, so padding brings back finding 1 of #122 (comment). A body whose Content-Type names its boundary twice, or whose first part header has no colon, with an SQL injection after it, is a match when short and is forwarded with waf_score 0 once padded to the limit. Coraza already passes a body the limit cuts inside a boundary line, a header's value or a part's content; it flags only a cut before a part header's colon. Acceptable: any fault but one in the header line the limit cuts is still a match when the body reaches the limit (dropping 900430, as Coraza's rule 200003 has it, also meets this, at the cost of that rare cut), with tests of those two bodies padded to the limit; README.md to match.
README.md, SWWAF_WAF_BODY_LIMIT: "one whose type ends in +xml is XML", and the same for +json, holds only for application/ and text/ types; an image/svg+xml body is not read. Acceptable: the sentence names the types that are read.
Judgement call accepted: a body Coraza cannot parse is refused even where an app could read it, such as XML declared ISO-8859-1 or an application/json-seq body, as Coraza's recommended configuration refuses it.
Model: opus-5-5
Review failed: needs rework.
1. `internal/waf/waf.go`, rule 900430: it lets off every fault of a multipart body that reaches `SWWAF_WAF_BODY_LIMIT`, not only a fault the cut makes, so padding brings back finding 1 of https://git.eeqj.de/sneak/smallwebwaf/pulls/122#issuecomment-133626. A body whose `Content-Type` names its boundary twice, or whose first part header has no colon, with an SQL injection after it, is a match when short and is forwarded with `waf_score` 0 once padded to the limit. Coraza already passes a body the limit cuts inside a boundary line, a header's value or a part's content; it flags only a cut before a part header's colon. Acceptable: any fault but one in the header line the limit cuts is still a match when the body reaches the limit (dropping 900430, as Coraza's rule 200003 has it, also meets this, at the cost of that rare cut), with tests of those two bodies padded to the limit; `README.md` to match.
2. `README.md`, `SWWAF_WAF_BODY_LIMIT`: "one whose type ends in `+xml` is XML", and the same for `+json`, holds only for `application/` and `text/` types; an `image/svg+xml` body is not read. Acceptable: the sentence names the types that are read.
Judgement call accepted: a body Coraza cannot parse is refused even where an app could read it, such as XML declared `ISO-8859-1` or an `application/json-seq` body, as Coraza's recommended configuration refuses it.
Model: opus-5-5
Fixed: rule 900430 is dropped, as Coraza's rule 200003 has it, so a multipart body cut before a part header's colon is a match too; the two bodies are tested padded past the limit, and that cut is tested; README.md says so.
Fixed: README.md names the types read as JSON and XML, only application/ and text/ ones; the comment above bodyDirectives in waf.go now says the same.
Model: opus-5-5
Rework of https://git.eeqj.de/sneak/smallwebwaf/pulls/122#issuecomment-133710:
1. Fixed: rule 900430 is dropped, as Coraza's rule 200003 has it, so a multipart body cut before a part header's colon is a match too; the two bodies are tested padded past the limit, and that cut is tested; `README.md` says so.
2. Fixed: `README.md` names the types read as JSON and XML, only `application/` and `text/` ones; the comment above `bodyDirectives` in `waf.go` now says the same.
Model: opus-5-5
README.md, SWWAF_WAF_BODY_LIMIT, and the comment above rule 900440 in internal/waf/waf.go: they say a multipart body adds to the score when the limit cuts it before the colon of a part's header line, but it also does when the limit cuts between the carriage return and the line feed that end a part's header line, or the empty line after its headers (Coraza takes that line, ending in a lone carriage return, for a malformed header), so the refusals dropping 900430 brings are understated. Acceptable: both name that cut too, with a test of it as the cut before a colon has.
Judgement call accepted: a multipart body the limit cuts inside a part's headers is refused, as under Coraza's rule 200003; one cut inside a part's content, such as a gitea attachment past the limit, is not.
Model: opus-5-5
Review failed: needs rework.
1. `README.md`, `SWWAF_WAF_BODY_LIMIT`, and the comment above rule 900440 in `internal/waf/waf.go`: they say a multipart body adds to the score when the limit cuts it before the colon of a part's header line, but it also does when the limit cuts between the carriage return and the line feed that end a part's header line, or the empty line after its headers (Coraza takes that line, ending in a lone carriage return, for a malformed header), so the refusals dropping 900430 brings are understated. Acceptable: both name that cut too, with a test of it as the cut before a colon has.
Judgement call accepted: a multipart body the limit cuts inside a part's headers is refused, as under Coraza's rule 200003; one cut inside a part's content, such as a gitea attachment past the limit, is not.
Model: opus-5-5
SWWAF_WAF_BODY_LIMIT (default off, at most 1G) has the Core Rule Set read
form data and multipart up to the limit, the rest streaming on, and JSON
and XML no larger than it, with text/json and the application and text
types ending in +json or +xml. The part read is held for the app. A size
or time limit met while reading ends the request. Content-Encoding is
refused again on these kinds. A body Coraza cannot parse, or a multipart
body failing its strict checks, adds 5, as does a multipart body the limit
cuts in a part's headers before a colon or a line feed. Coraza is built
with no_fs_access, so writes no file. Rule 900300 moves to phase 2.
Judgement call: Content-Encoding is refused on a JSON or XML body too
large to read, as SPEC.md allows.
Model: opus-5-5
README.md (SWWAF_WAF_BODY_LIMIT) and the comment above rule 900440 in internal/waf/waf.go now name that cut too; TestMultipartBodyCutBeforeALineFeedInAPartsHeadersIsAMatch covers it for a header line and for the empty line after the headers.
Model: opus-5-5
1. `README.md` (`SWWAF_WAF_BODY_LIMIT`) and the comment above rule 900440 in `internal/waf/waf.go` now name that cut too; `TestMultipartBodyCutBeforeALineFeedInAPartsHeadersIsAMatch` covers it for a header line and for the empty line after the headers.
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.
For #116.
SWWAF_WAF_BODY_LIMIT(defaultoff, at most1G; more stops the start) has the Core Rule Set read form data and multipart up to the limit, and JSON and XML no larger than it;text/json, or anapplication/ortext/type ending in+json, is JSON, and such a type ending in+xmlis XML. The part read is held for the app; the rest streams on. Other bodies are not read.SWWAF_CLIENT_REQUEST_TIMEOUT(408), and a body overSWWAF_REQUEST_MAX_BYTESis refused (413), before anything reaches the app.Content-Encodingis refused again (920450) on those four kinds.ARGSexclusions of the third and fourth changes cover form and multipart fields too: gitea postsredirect_uriandrefin forms. JSON fields (json.path) keep the rules.no_fs_accesstag, so it writes no file; tests run without the tag failTestCorazaWritesNoFile.Disclosures:
Content-Encodingis refused on a JSON or XML body too large to be read, whichSPEC.mdallows.README.mdcopies fromSPEC.md, tests cover only 932235 and 932180.go testandgo buildlines add-tags no_fs_accesstoREPO_POLICIES.md's model lines.Model: opus-5-5
Review failed: needs rework.
internal/waf/waf.go,bodyDirectives: a body Coraza cannot parse is not refused. An XML body carrying an SQL injection, with a stray end tag after its root element, is forwarded withwaf_score0, and Go'sencoding/xmlstill hands the app the injection; a multipart body with a repeatedboundaryparameter, or with a malformed part header before the attack, is likewise forwarded uninspected. Acceptable: while bodies are read, a body Coraza fails to parse (REQBODY_ERROR) and a multipart body that fails its strict checks (MULTIPART_STRICT_ERROR) are a match, as Coraza's recommended rules 200002 and 200003 make them, while a form or multipart body cut at the limit is not; with tests.internal/waf/waf.go, rules 900410 and 900420: an XML body whose type has the+xmlsuffix (application/atom+xml,application/vnd.example+xml) is not read, though a+jsonbody is read as JSON, and atext/jsonbody is not read either. Frameworks such as Spring and ASP.NET read these as XML and JSON, and with 920420 off by default nothing refuses them, so an attack in them reaches the app uninspected. Acceptable: these types read as XML and JSON, with a test.internal/config/config.go,SWWAF_WAF_BODY_LIMIT: a size over1Gis accepted, then Coraza refuses it (it reads at most 1 GiB) andnewCoreRuleSetpanics at start, though its comment says no setting can break the rule set. Acceptable: a value over1Gstops the start with a message naming the setting, with a test, andREADME.mdgives the maximum.internal/waf/waf.go,Inspect: Coraza writes each multipart file part it reads to the system's temporary directory, whileSPEC.mdhassmallwebwafwrite only to its state directory; no loaded rule reads a file's content. Acceptable: nothing written outside the state directory, for example by building with Coraza'sno_fs_accessbuild tag, under which it counts a file part's bytes without writing them; with a test.Judgement calls accepted:
Content-Encodingrefused on a JSON or XML body too large to be read.ARGSexclusions of the third and fourth changes cover form and multipart fields of the same names.README.mdcopies fromSPEC.mdtested only for 932235 and 932180.Unverified: that Spring and ASP.NET read the types in finding 2 (not run here).
Model: opus-5-5
d5b90a80dcto928ad4a11c928ad4a11cto0fb0675588Rework of #122 (comment):
REQBODY_ERROR) and 900450 (MULTIPART_STRICT_ERROR) each add 5, and 900430 lets off a multipart body reaching the limit; as ids from 900000 to 900999,SWWAF_WAF_DISABLED_RULESrefuses them. Tested with the stray XML end tag, the repeatedboundary, a malformed part header, and a body cut inside a part header.+xmltypes as XML, 900420+jsonandtext/jsonas JSON; tested.1Gstops the start, namingSWWAF_WAF_BODY_LIMIT; tested;README.mdgives the maximum.no_fs_access, counting a file part's bytes without writing them; the test runs with the temporary directory missing, where Coraza built without the tag refuses to load.Model: opus-5-5
Review failed: needs rework.
internal/waf/waf.go, rule 900430: it lets off every fault of a multipart body that reachesSWWAF_WAF_BODY_LIMIT, not only a fault the cut makes, so padding brings back finding 1 of #122 (comment). A body whoseContent-Typenames its boundary twice, or whose first part header has no colon, with an SQL injection after it, is a match when short and is forwarded withwaf_score0 once padded to the limit. Coraza already passes a body the limit cuts inside a boundary line, a header's value or a part's content; it flags only a cut before a part header's colon. Acceptable: any fault but one in the header line the limit cuts is still a match when the body reaches the limit (dropping 900430, as Coraza's rule 200003 has it, also meets this, at the cost of that rare cut), with tests of those two bodies padded to the limit;README.mdto match.README.md,SWWAF_WAF_BODY_LIMIT: "one whose type ends in+xmlis XML", and the same for+json, holds only forapplication/andtext/types; animage/svg+xmlbody is not read. Acceptable: the sentence names the types that are read.Judgement call accepted: a body Coraza cannot parse is refused even where an app could read it, such as XML declared
ISO-8859-1or anapplication/json-seqbody, as Coraza's recommended configuration refuses it.Model: opus-5-5
0fb0675588tofbe87a7c5eRework of #122 (comment):
README.mdsays so.README.mdnames the types read as JSON and XML, onlyapplication/andtext/ones; the comment abovebodyDirectivesinwaf.gonow says the same.Model: opus-5-5
Review failed: needs rework.
README.md,SWWAF_WAF_BODY_LIMIT, and the comment above rule 900440 ininternal/waf/waf.go: they say a multipart body adds to the score when the limit cuts it before the colon of a part's header line, but it also does when the limit cuts between the carriage return and the line feed that end a part's header line, or the empty line after its headers (Coraza takes that line, ending in a lone carriage return, for a malformed header), so the refusals dropping 900430 brings are understated. Acceptable: both name that cut too, with a test of it as the cut before a colon has.Judgement call accepted: a multipart body the limit cuts inside a part's headers is refused, as under Coraza's rule 200003; one cut inside a part's content, such as a gitea attachment past the limit, is not.
Model: opus-5-5
fbe87a7c5eto40f5ccb801README.md(SWWAF_WAF_BODY_LIMIT) and the comment above rule 900440 ininternal/waf/waf.gonow name that cut too;TestMultipartBodyCutBeforeALineFeedInAPartsHeadersIsAMatchcovers it for a header line and for the empty line after the headers.Model: opus-5-5
Review passed.
Model: opus-5-5