Coraza v3.8.1 is a security release. It completes several fixes that shipped in v3.8.0 and fixes a process crash. All users should upgrade, including those still on v3.7.x and earlier, which are affected by most of these issues too.
Security fixes
| Advisory | Severity | Summary |
|---|---|---|
| GHSA-6gcq-wc29-5xf2 | High | Deeply nested JSON request or response bodies could crash the process (unrecoverable stack overflow). JSON nesting is now bounded by an iterative pre-scan before validation (ADR-0060). |
| GHSA-6r3q-mjv7-xr8m | High | Completes the v3.8.0 fix: JSON array-length entries are now held to the flattening byte budget, closing a memory-exhaustion path. |
| GHSA-5gj4-9gm7-2fx2 | Medium | Completes the v3.8.0 fix: JSON keys that differ only in case no longer overwrite each other in ARGS_POST / RESPONSE_ARGS.
|
| GHSA-w253-m66g-rx24 | Medium | Completes the v3.8.0 fix: only the first Content-Type header selects the body processor, and leading whitespace in the media type is trimmed the way mime.ParseMediaType does it.
|
| GHSA-3wr7-993q-jrff | Medium | Completes the v3.8.0 fix: RFC 2231 filename*N continuations next to a filename* parameter now set MULTIPART_STRICT_ERROR. Also fixes a CPU-exhaustion path in the Content-Disposition duplicate-parameter check, which v3.8.0 introduced.
|
| GHSA-g4qm-m288-5cp9 | Medium | Completes the v3.8.0 fix: a cookie whose name is empty, or contains only control characters, is now inspected under the name "" instead of being dropped. A regex ctl:ruleRemoveTargetBy* exclusion no longer also removes keys named "" from ARGS, REQUEST_COOKIES or any other collection.
|
Bug fixes
- fix(bodyprocessors): don't flag multipart strict error on ProcessPartial truncation by @M4tteoP in #1725
Regression in v3.8.0: withSecRequestBodyLimitAction ProcessPartial, rule 200003 rejected every multipart upload larger than the body limit. - fix(bodyprocessors): make multipart duplicate-param check linear by @fzipi in #1726
- fix(bodyprocessors): report JSON flatten budget overrun as a body error by @M4tteoP in #1730
- fix(json bodyprocessor): don't count JSON array-length entries toward SecArgumentsLimit by @M4tteoP in #1729
A JSON array with exactlySecArgumentsLimitelements was rejected in v3.8.0.
Documentation and chores
- docs: clarify SecArgumentsLimit scope and enable it in coraza.conf-recommended by @M4tteoP in #1727
- docs(variables): fix stale multipart variable docs by @M4tteoP in #1728
- docs(security): score exploitability preconditions during triage by @fzipi in #1722
- chore: add .coderabbit.yaml with organization inheritance by @fzipi in #1721
Behaviour changes
Coming from v3.8.0:
- Duplicate
Content-Typeheaders: the first header now selects the body processor, matching whatHeader.Get(and so a typical backend) reads. Before, the last matching header won. filename*with numbered continuations (filename*0=,filename*0*=, ...): the request now setsMULTIPART_STRICT_ERROR, so rule 200003 in the recommended config rejects it with 400.- JSON bodies over the flattening memory budget now set
REQBODY_ERROR, so rule 200002 rejects them with 400. Before, they were only truncated. - Empty cookie names:
REQUEST_COOKIESandREQUEST_COOKIES_NAMEScan now contain an entry named""(e.g. fromCookie: =value), and&REQUEST_COOKIEScounts it. This is an intentional deviation: ModSecurity v2 and v3 skip such cookies, but some backends (e.g. Node'scookiepackage) pass them to the application. A bare=is still skipped. - Regex
ctltarget removals (ctl:ruleRemoveTargetById=N;ARGS:/re/) no longer remove entries named""unless the regex matches the empty string. - JSON array-length entries (
json.a= array length) no longer count towardSecArgumentsLimit. coraza.conf-recommended:SecArgumentsLimit 1000is now set explicitly; before it was commented out. The limit applies per source (ARGS_GET,ARGS_PATH,ARGS_POST,RESPONSE_ARGS). The commented-out examples no longer reuse rule ids 200004 and 200005.
Important
Running without the recommended config's rules 200004 and 200005? SecArgumentsLimit defaults to 1000 even when it is not set. Since v3.8.0, arguments beyond that limit, from the query string and from urlencoded or JSON bodies, are dropped from the tail and only ARGUMENTS_LIMIT_REACHED is set. A config with no rule acting on that flag (e.g. CRS on its own, or an older vendored copy of coraza.conf-recommended) does not inspect those arguments. Add rules 200004 and 200005 from coraza.conf-recommended, or an equivalent rule on ARGUMENTS_LIMIT_REACHED.
Coming from v3.7.x, also read the v3.8.0 release notes. Of note:
SecArgumentsLimit(default 1000) now also applies to urlencoded and JSON request bodies. Requests that exceed it are rejected by rules 200004/200005. Raise the limit if your APIs legitimately send more values.- New rule 200009 in
coraza.conf-recommendedreturns 400 for URIs that fail to parse: invalid path escapes (/50%off,%zz), a bad port, or no leading/. URLENCODED_ERRORis no longer set when the request URI fails to parse. Use the newURI_PARSE_ERRORvariable instead; rule 200009 relies on it.- Rule 200003 now returns 400 for multipart parts with malformed or duplicate headers, which previously hid uploaded files from rule inspection. A part with only
filename*now goes toFILESinstead ofARGS_POST. - New methods on
plugintypes.TransactionVariablesbreak external implementations at compile time. - New
types/variablesconstants were inserted mid-iota, which renumbers the constants after them.
Known limitations
These are tracked for a later release:
- Multipart form fields are not counted against
SecArgumentsLimit. SecUploadFileLimitis parsed but not enforced.
Full Changelog: v3.8.0...v3.8.1