github corazawaf/coraza v3.8.1

3 hours ago

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: with SecRequestBodyLimitAction 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 exactly SecArgumentsLimit elements 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-Type headers: the first header now selects the body processor, matching what Header.Get (and so a typical backend) reads. Before, the last matching header won.
  • filename* with numbered continuations (filename*0=, filename*0*=, ...): the request now sets MULTIPART_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_COOKIES and REQUEST_COOKIES_NAMES can now contain an entry named "" (e.g. from Cookie: =value), and &REQUEST_COOKIES counts it. This is an intentional deviation: ModSecurity v2 and v3 skip such cookies, but some backends (e.g. Node's cookie package) pass them to the application. A bare = is still skipped.
  • Regex ctl target 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 toward SecArgumentsLimit.
  • coraza.conf-recommended: SecArgumentsLimit 1000 is 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-recommended returns 400 for URIs that fail to parse: invalid path escapes (/50%off, %zz), a bad port, or no leading /.
  • URLENCODED_ERROR is no longer set when the request URI fails to parse. Use the new URI_PARSE_ERROR variable 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 to FILES instead of ARGS_POST.
  • New methods on plugintypes.TransactionVariables break external implementations at compile time.
  • New types/variables constants 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.
  • SecUploadFileLimit is parsed but not enforced.

Full Changelog: v3.8.0...v3.8.1

Don't miss a new coraza release

NewReleases is sending notifications on new releases.